]> git.bundesbrandschatzamt.de Git - emacsconfig.git/commitdiff
add Bookmark plus
authorAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Fri, 11 Feb 2022 15:55:16 +0000 (16:55 +0100)
committerAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Sat, 26 Feb 2022 10:49:19 +0000 (11:49 +0100)
Signed-off-by: Andreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
bba.org
lisp/bookmark+-1.el [new file with mode: 0644]
lisp/bookmark+-bmu.el [new file with mode: 0644]
lisp/bookmark+-chg.el [new file with mode: 0644]
lisp/bookmark+-doc.el [new file with mode: 0644]
lisp/bookmark+-key.el [new file with mode: 0644]
lisp/bookmark+-lit.el [new file with mode: 0644]
lisp/bookmark+-mac.el [new file with mode: 0644]
lisp/bookmark+.el [new file with mode: 0644]

diff --git a/bba.org b/bba.org
index 7ed0726dfa5705df18c490bf6cf50cd32e837ecb..98fd3eb49d5977e131e11670ce680d2762338ef3 100644 (file)
--- a/bba.org
+++ b/bba.org
@@ -332,6 +332,23 @@ Keep track of your important stuff!
 
   (define-key calendar-mode-map (kbd "RET") 'calendar-insert-date)
 #+end_src
+
+* [[https://www.emacswiki.org/emacs/BookmarkPlus][Bookmark+]]
+[2022-02-10 Thu 15:22]
+
+#+BEGIN_SRC emacs-lisp
+  (if (equal "work" (getenv "SYSENV"))
+      (setq bookmark-default-file "~/workorg/bookmarks")
+    (setq bookmark-default-file "~/org/bookmarks"))
+  (load-file (expand-file-name "~/.emacs.d/lisp/bookmark+.el"))
+  (load-file (expand-file-name "~/.emacs.d/lisp/bookmark+-mac.el"))
+  (load-file (expand-file-name "~/.emacs.d/lisp/bookmark+-bmu.el"))
+  (load-file (expand-file-name "~/.emacs.d/lisp/bookmark+-1.el"))
+  (load-file (expand-file-name "~/.emacs.d/lisp/bookmark+-key.el"))
+  (load-file (expand-file-name "~/.emacs.d/lisp/bookmark+-lit.el"))
+
+#+END_SRC
+
 * magit
 
 For annotated tags prepare message with commit messages since last tag.
diff --git a/lisp/bookmark+-1.el b/lisp/bookmark+-1.el
new file mode 100644 (file)
index 0000000..e8ea6df
--- /dev/null
@@ -0,0 +1,13889 @@
+;;; bookmark+-1.el - First part of package Bookmark+.
+;;
+;; Filename: bookmark+-1.el
+;; Description: First part of package Bookmark+.
+;; Author: Drew Adams, Thierry Volpiatto
+;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com")
+;; Copyright (C) 2000-2022, Drew Adams, all rights reserved.
+;; Copyright (C) 2009, Thierry Volpiatto.
+;; Created: Mon Jul 12 13:43:55 2010 (-0700)
+;; Last-Updated: Fri Jan 14 12:34:36 2022 (-0800)
+;;           By: dradams
+;;     Update #: 9453
+;; URL: https://www.emacswiki.org/emacs/download/bookmark%2b-1.el
+;; Doc URL: https://www.emacswiki.org/emacs/BookmarkPlus
+;; Keywords: bookmarks, bookmark+, placeholders, annotations, search, info, url, eww, w3m, gnus
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x, 24.x, 25.x, 26.x
+;;
+;; Features that might be required by this library:
+;;
+;;   `backquote', `bookmark', `bookmark+-1', `button', `bytecomp',
+;;   `cconv', `cl-lib', `col-highlight', `crosshairs', `font-lock',
+;;   `font-lock+', `help-mode', `hl-line', `hl-line+', `kmacro',
+;;   `macroexp', `pp', `replace', `syntax', `text-mode', `thingatpt',
+;;   `thingatpt+', `vline'.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;    The Bookmark+ libraries are these:
+;;
+;;    `bookmark+.el'     - main (driver) library
+;;    `bookmark+-mac.el' - Lisp macros
+;;    `bookmark+-lit.el' - (optional) code for highlighting bookmarks
+;;    `bookmark+-bmu.el' - code for the `*Bookmark List*' (bmenu)
+;;    `bookmark+-1.el'   - other (non-bmenu) required code (this file)
+;;    `bookmark+-key.el' - key and menu bindings
+;;
+;;    `bookmark+-doc.el' - documentation (comment-only file)
+;;    `bookmark+-chg.el' - change log (comment-only file)
+;;
+;;    The documentation (in `bookmark+-doc.el') includes how to
+;;    byte-compile and install Bookmark+.  The documentation is also
+;;    available in these ways:
+;;
+;;    1. From the bookmark list (`C-x r l'):
+;;       Use `?' to show the current bookmark-list status and general
+;;       help, then click link `Doc in Commentary' or link `Doc on the
+;;       Web'.
+;;
+;;    2. From the Emacs-Wiki Web site:
+;;       https://www.emacswiki.org/emacs/BookmarkPlus.
+;;
+;;    3. From the Bookmark+ group customization buffer:
+;;       `M-x customize-group bookmark-plus', then click link
+;;       `Commentary'.
+;;
+;;    (The commentary links in #1 and #3 work only if you have library
+;;    `bookmark+-doc.el' in your `load-path'.)
+ 
+;;(@> "Index")
+;;
+;;  Index
+;;  -----
+;;
+;;  If you have library `linkd.el' and Emacs 22 or later, load
+;;  `linkd.el' and turn on `linkd-mode' now.  It lets you easily
+;;  navigate around the sections of this doc.  Linkd mode will
+;;  highlight this Index, as well as the cross-references and section
+;;  headings throughout this file.  You can get `linkd.el' here:
+;;  https://www.emacswiki.org/emacs/download/linkd.el.
+;;
+;;  (@> "Things Defined Here")
+;;  (@> "User Options (Customizable)")
+;;  (@> "Internal Variables")
+;;  (@> "Compatibility Code for Older Emacs Versions")
+;;  (@> "Core Replacements (`bookmark-*' except `bookmark-bmenu-*')")
+;;  (@> "Bookmark+ Functions (`bmkp-*')")
+;;    (@> "Search-and-Replace Locations of Marked Bookmarks")
+;;    (@> "Tags")
+;;    (@> "Bookmark Predicates")
+;;    (@> "Filter Functions")
+;;    (@> "General Utility Functions")
+;;    (@> "Bookmark Entry Access Functions")
+;;    (@> "Sorting - General Functions")
+;;    (@> "Sorting - Commands")
+;;    (@> "Sorting - General Predicates")
+;;    (@> "Sorting - File-Name Predicates")
+;;    (@> "Indirect Bookmarking Functions")
+;;    (@> "Other Bookmark+ Functions (`bmkp-*')")
+;;  (@> "Keymaps")
+ 
+;;(@* "Things Defined Here")
+;;
+;;  Things Defined Here
+;;  -------------------
+;;
+;;  Commands defined here:
+;;
+;;    `bmkp-add-tags', `bmkp-all-tags-jump',
+;;    `bmkp-all-tags-jump-other-window', `bmkp-all-tags-regexp-jump',
+;;    `bmkp-all-tags-regexp-jump-other-window',
+;;    `bmkp-annotate-all-bookmarks-this-file/buffer',
+;;    `bmkp-annotate-bookmark',
+;;    `bmkp-annotate-bookmark-this-file/buffer',
+;;    `bmkp-autofile-add-tags', `bmkp-autofile-all-tags-jump',
+;;    `bmkp-autofile-all-tags-jump-other-window',
+;;    `bmkp-autofile-all-tags-regexp-jump',
+;;    `bmkp-autofile-all-tags-regexp-jump-other-window',
+;;    `bmkp-autofile-jump', `bmkp-autofile-jump-other-window',
+;;    `bmkp-autofile-remove-tags', `bmkp-autofile-set',
+;;    `bmkp-autofile-some-tags-jump',
+;;    `bmkp-autofile-some-tags-jump-other-window',
+;;    `bmkp-autofile-some-tags-regexp-jump',
+;;    `bmkp-autofile-some-tags-regexp-jump-other-window',
+;;    `bmkp-automatic-bookmark-mode', `bmkp-autonamed-jump',
+;;    `bmkp-autonamed-jump-other-window',
+;;    `bmkp-autonamed-this-buffer-jump',
+;;    `bmkp-autonamed-this-buffer-jump-other-window',
+;;    `bmkp-bookmark-a-file' `bmkp-bookmark-file-jump',
+;;    `bmkp-bookmark-file-load-jump',
+;;    `bmkp-bookmark-file-switch-jump', `bmkp-bookmark-linked-at'
+;;    (Emacs 22+), `bmkp-bookmark-linked-at-mouse' (Emacs 22+),
+;;    `bmkp-bookmark-list-jump',
+;;    `bmkp-bookmark-set-confirm-overwrite',
+;;    `bmkp-choose-navlist-from-bookmark-list',
+;;    `bmkp-choose-navlist-of-type', `bmkp-clone-bookmark',
+;;    `bmkp-compilation-target-set',
+;;    `bmkp-compilation-target-set-all', `bmkp-copy-bookmark',
+;;    `bmkp-convert-eww-bookmarks' (Emacs 25+), `bmkp-copy-tags',
+;;    `bmkp-crosshairs-highlight', `bmkp-cycle',
+;;    `bmkp-cycle-autonamed', `bmkp-cycle-autonamed-other-window',
+;;    `bmkp-cycle-bookmark-list',
+;;    `bmkp-cycle-bookmark-list-other-window', `bmkp-cycle-desktop',
+;;    `bmkp-cycle-dired', `bmkp-cycle-dired-other-window',
+;;    `bmkp-cycle-eww', `bmkp-cycle-eww-other-window',
+;;    `bmkp-cycle-file', `bmkp-cycle-file-other-window',
+;;    `bmkp-cycle-gnus', `bmkp-cycle-gnus-other-window',
+;;    `bmkp-cycle-info', `bmkp-cycle-info-other-window',
+;;    `bmkp-cycle-lighted', `bmkp-cycle-lighted-other-window',
+;;    `bmkp-cycle-local-file', `bmkp-cycle-local-file-other-window',
+;;    `bmkp-cycle-man', `bmkp-cycle-man-other-window',
+;;    `bmkp-cycle-non-file', `bmkp-cycle-non-file-other-window',
+;;    `bmkp-cycle-other-window', `bmkp-cycle-remote-file',
+;;    `bmkp-cycle-remote-file-other-window',
+;;    `bmkp-cycle-specific-buffers',
+;;    `bmkp-cycle-specific-buffers-other-window',
+;;    `bmkp-cycle-specific-files',
+;;    `bmkp-cycle-specific-files-other-window',
+;;    `bmkp-cycle-this-buffer', `bmkp-cycle-this-buffer-other-window',
+;;    `bmkp-cycle-this-file', `bmkp-cycle-this-file/buffer',
+;;    `bmkp-cycle-this-file/buffer-other-window',
+;;    `bmkp-cycle-this-file-other-window', `bmkp-cycle-variable-list',
+;;    `bmkp-cycle-url', `bmkp-cycle-url-other-window',
+;;    `bmkp-delete-all-autonamed-for-this-buffer',
+;;    `bmkp-delete-all-temporary-bookmarks', `bmkp-delete-bookmarks',
+;;    `bmkp-describe-bookmark', `bmkp-describe-bookmark-internals',
+;;    `bmkp-desktop-change-dir', `bmkp-desktop-delete',
+;;    `bmkp-desktop-jump', `bmkp-desktop-read', `bmkp-dired-jump',
+;;    `bmkp-dired-jump-other-window', `bmkp-dired-this-dir-jump',
+;;    `bmkp-dired-this-dir-jump-other-window',
+;;    `bmkp-edit-bookmark-name-and-location',
+;;    `bmkp-edit-bookmark-record',
+;;    `bmkp-edit-bookmark-record-file/buffer',
+;;    `bmkp-edit-bookmark-record-send',
+;;    `bmkp-edit-bookmark-records-send', `bmkp-edit-tags',
+;;    `bmkp-edit-tags-send', `bmkp-edit-this-annotation',
+;;    `bmkp-empty-file', `bmkp-eww-jump' (Emacs 25+),
+;;    `bmkp-eww-jump-other-window' (Emacs 25+),
+;;    `bmkp-eww-auto-bookmark-mode' (Emacs 25+),
+;;    `bmkp-ffap-max-region-size', `bmkp-file-target-set',
+;;    `bmkp-file-all-tags-jump',
+;;    `bmkp-file-all-tags-jump-other-window',
+;;    `bmkp-file-all-tags-regexp-jump',
+;;    `bmkp-file-all-tags-regexp-jump-other-window', `bmkp-file-jump',
+;;    `bmkp-file-jump-other-window', `bmkp-file-some-tags-jump',
+;;    `bmkp-file-some-tags-jump-other-window',
+;;    `bmkp-file-some-tags-regexp-jump',
+;;    `bmkp-file-some-tags-regexp-jump-other-window',
+;;    `bmkp-file-this-dir-all-tags-jump',
+;;    `bmkp-file-this-dir-all-tags-jump-other-window',
+;;    `bmkp-file-this-dir-all-tags-regexp-jump',
+;;    `bmkp-file-this-dir-all-tags-regexp-jump-other-window',
+;;    `bmkp-file-this-dir-jump',
+;;    `bmkp-file-this-dir-jump-other-window',
+;;    `bmkp-file-this-dir-some-tags-jump',
+;;    `bmkp-file-this-dir-some-tags-jump-other-window',
+;;    `bmkp-file-this-dir-some-tags-regexp-jump',
+;;    `bmkp-file-this-dir-some-tags-regexp-jump-other-window',
+;;    `bmkp-find-file', `bmkp-find-file-other-window',
+;;    `bmkp-find-file-all-tags',
+;;    `bmkp-find-file-all-tags-other-window',
+;;    `bmkp-find-file-all-tags-regexp',
+;;    `bmkp-find-file-all-tags-regexp-other-window',
+;;    `bmkp-find-file-some-tags',
+;;    `bmkp-find-file-some-tags-other-window',
+;;    `bmkp-find-file-some-tags-regexp',
+;;    `bmkp-find-file-some-tags-regexp-other-window',
+;;    `bmkp-get-external-annotation',
+;;    `bmkp-global-automatic-bookmark-mode' (Emacs 21+),
+;;    `bmkp-gnus-jump', `bmkp-gnus-jump-other-window',
+;;    `bmkp-image-jump', `bmkp-image-jump-other-window',
+;;    `bmkp-info-auto-bookmark-mode' (Emacs 22+), `bmkp-info-jump',
+;;    `bmkp-info-jump-other-window', `bmkp-insert-bookmark-link'
+;;    (Emacs 22+), `bmkp-jump-in-navlist',
+;;    `bmkp-jump-in-navlist-other-window',
+;;    `bmkp-jump-to-bookmark-linked-at' (Emacs 22+),
+;;    `bmkp-jump-to-bookmark-linked-at-mouse' (Emacs 22+),
+;;    `bmkp-jump-to-list', `bmkp-jump-to-type',
+;;    `bmkp-jump-to-type-other-window', `bmkp-list-all-tags',
+;;    `bmkp-list-defuns-in-commands-file', `bmkp-local-file-jump',
+;;    `bmkp-local-file-jump-other-window',
+;;    `bmkp-local-non-dir-file-jump',
+;;    `bmkp-local-non-dir-file-jump-other-window',
+;;    `bmkp-make-bookmark-savable', `bmkp-make-bookmark-temporary',
+;;    `bmkp-make-function-bookmark', `bmkp-man-jump',
+;;    `bmkp-man-jump-other-window', `bmkp-menu-jump-other-window'
+;;    (Emacs 20, 21), `bmkp-navlist-bmenu-list',
+;;    `bmkp-next-autonamed-bookmark',
+;;    `bmkp-next-autonamed-bookmark-other-window',
+;;    `bmkp-next-autonamed-bookmark-other-window-repeat',
+;;    `bmkp-next-autonamed-bookmark-repeat', `bmkp-next-bookmark',
+;;    `bmkp-next-bookmark-list-bookmark',
+;;    `bmkp-next-bookmark-list-bookmark-other-window',
+;;    `bmkp-next-bookmark-list-bookmark-other-window-repeat',
+;;    `bmkp-next-bookmark-list-bookmark-repeat',
+;;    `bmkp-next-bookmark-other-window',
+;;    `bmkp-next-bookmark-other-window-repeat',
+;;    `bmkp-next-bookmark-repeat', `bmkp-next-bookmark-this-buffer',
+;;    `bmkp-next-bookmark-this-buffer-other-window',
+;;    `bmkp-next-bookmark-this-buffer-other-window-repeat',
+;;    `bmkp-next-bookmark-this-buffer-repeat',
+;;    `bmkp-next-bookmark-this-file',
+;;    `bmkp-next-bookmark-this-file/buffer',
+;;    `bmkp-next-bookmark-this-file/buffer-other-window',
+;;    `bmkp-next-bookmark-this-file/buffer-other-window-repeat',
+;;    `bmkp-next-bookmark-this-file/buffer-repeat',
+;;    `bmkp-next-bookmark-this-file-other-window',
+;;    `bmkp-next-bookmark-this-file-other-window-repeat',
+;;    `bmkp-next-bookmark-this-file-repeat',
+;;    `bmkp-next-desktop-bookmark',
+;;    `bmkp-next-desktop-bookmark-other-window',
+;;    `bmkp-next-desktop-bookmark-other-window-repeat',
+;;    `bmkp-next-desktop-bookmark-repeat', `bmkp-next-dired-bookmark',
+;;    `bmkp-next-dired-bookmark-other-window',
+;;    `bmkp-next-dired-bookmark-other-window-repeat',
+;;    `bmkp-next-dired-bookmark-repeat', `bmkp-next-eww-bookmark',
+;;    `bmkp-next-eww-bookmark-other-window',
+;;    `bmkp-next-eww-bookmark-other-window-repeat',
+;;    `bmkp-next-eww-bookmark-repeat', `bmkp-next-file-bookmark',
+;;    `bmkp-next-file-bookmark-other-window',
+;;    `bmkp-next-file-bookmark-other-window-repeat',
+;;    `bmkp-next-file-bookmark-repeat', `bmkp-next-gnus-bookmark',
+;;    `bmkp-next-gnus-bookmark-other-window',
+;;    `bmkp-next-gnus-bookmark-other-window-repeat',
+;;    `bmkp-next-gnus-bookmark-repeat', `bmkp-next-info-bookmark',
+;;    `bmkp-next-info-bookmark-other-window',
+;;    `bmkp-next-info-bookmark-other-window-repeat',
+;;    `bmkp-next-info-bookmark-repeat', `bmkp-next-lighted-bookmark',
+;;    `bmkp-next-lighted-bookmark-other-window',
+;;    `bmkp-next-lighted-bookmark-other-window-repeat',
+;;    `bmkp-next-lighted-bookmark-repeat',
+;;    `bmkp-next-local-file-bookmark',
+;;    `bmkp-next-local-file-bookmark-other-window',
+;;    `bmkp-next-local-file-bookmark-other-window-repeat',
+;;    `bmkp-next-local-file-bookmark-repeat',
+;;    `bmkp-next-man-bookmark', `bmkp-next-man-bookmark-other-window',
+;;    `bmkp-next-man-bookmark-other-window-repeat',
+;;    `bmkp-next-man-bookmark-repeat', `bmkp-next-non-file-bookmark',
+;;    `bmkp-next-non-file-bookmark-other-window',
+;;    `bmkp-next-non-file-bookmark-other-window-repeat',
+;;    `bmkp-next-non-file-bookmark-repeat',
+;;    `bmkp-next-remote-file-bookmark',
+;;    `bmkp-next-remote-file-bookmark-other-window',
+;;    `bmkp-next-remote-file-bookmark-other-window-repeat',
+;;    `bmkp-next-remote-file-bookmark-repeat',
+;;    `bmkp-next-specific-buffers-bookmark',
+;;    `bmkp-next-specific-buffers-bookmark-other-window',
+;;    `bmkp-next-specific-buffers-bookmark-other-window-repeat',
+;;    `bmkp-next-specific-buffers-bookmark-repeat',
+;;    `bmkp-next-specific-files-bookmark',
+;;    `bmkp-next-specific-files-bookmark-other-window',
+;;    `bmkp-next-specific-files-bookmark-other-window-repeat',
+;;    `bmkp-next-specific-files-bookmark-repeat',
+;;    `bmkp-next-variable-list-bookmark',
+;;    `bmkp-next-variable-list-bookmark-other-window',
+;;    `bmkp-next-variable-list-bookmark-other-window-repeat',
+;;    `bmkp-next-variable-list-bookmark-repeat',
+;;    `bmkp-next-url-bookmark', `bmkp-next-url-bookmark-other-window',
+;;    `bmkp-next-url-bookmark-other-window-repeat',
+;;    `bmkp-next-url-bookmark-repeat', `bmkp-next-bookmark-w32',
+;;    `bmkp-next-bookmark-w32-other-window',
+;;    `bmkp-next-bookmark-w32-other-window-repeat',
+;;    `bmkp-next-bookmark-w32-repeat', `bmkp-non-dir-file-jump',
+;;    `bmkp-non-dir-file-jump-other-window', `bmkp-non-file-jump',
+;;    `bmkp-non-file-jump-other-window',
+;;    `bmkp-occur-create-autonamed-bookmarks',
+;;    `bmkp-ORIG-bookmark-insert', `bmkp-occur-target-set',
+;;    `bmkp-occur-target-set-all', `bmkp-paste-add-tags',
+;;    `bmkp-paste-replace-tags', `bmkp-previous-autonamed-bookmark',
+;;    `bmkp-previous-autonamed-bookmark-other-window',
+;;    `bmkp-previous-autonamed-bookmark-other-window-repeat',
+;;    `bmkp-previous-autonamed-bookmark-repeat',
+;;    `bmkp-previous-bookmark',
+;;    `bmkp-previous-bookmark-list-bookmark',
+;;    `bmkp-previous-bookmark-list-bookmark-other-window',
+;;    `bmkp-previous-bookmark-list-bookmark-other-window-repeat',
+;;    `bmkp-previous-bookmark-list-bookmark-repeat',
+;;    `bmkp-previous-bookmark-list-repeat',
+;;    `bmkp-previous-bookmark-other-window',
+;;    `bmkp-previous-bookmark-other-window-repeat',
+;;    `bmkp-previous-bookmark-repeat',
+;;    `bmkp-previous-bookmark-this-buffer',
+;;    `bmkp-previous-bookmark-this-buffer-other-window',
+;;    `bmkp-previous-bookmark-this-buffer-other-window-repeat',
+;;    `bmkp-previous-bookmark-this-buffer-repeat',
+;;    `bmkp-previous-bookmark-this-file',
+;;    `bmkp-previous-bookmark-this-file/buffer',
+;;    `bmkp-previous-bookmark-this-file/buffer-other-window',
+;;    `bmkp-previous-bookmark-this-file/buffer-other-window-repeat',
+;;    `bmkp-previous-bookmark-this-file/buffer-repeat',
+;;    `bmkp-previous-bookmark-this-file-other-window',
+;;    `bmkp-previous-bookmark-this-file-other-window-repeat',
+;;    `bmkp-previous-bookmark-this-file-repeat',
+;;    `bmkp-previous-desktop-bookmark',
+;;    `bmkp-previous-desktop-bookmark-other-window',
+;;    `bmkp-previous-desktop-bookmark-other-window-repeat',
+;;    `bmkp-previous-desktop-bookmark-repeat',
+;;    `bmkp-previous-dired-bookmark',
+;;    `bmkp-previous-dired-bookmark-other-window',
+;;    `bmkp-previous-dired-bookmark-other-window-repeat',
+;;    `bmkp-previous-dired-bookmark-repeat',
+;;    `bmkp-previous-eww-bookmark',
+;;    `bmkp-previous-eww-bookmark-other-window',
+;;    `bmkp-previous-eww-bookmark-other-window-repeat',
+;;    `bmkp-previous-eww-bookmark-repeat',
+;;    `bmkp-previous-file-bookmark',
+;;    `bmkp-previous-file-bookmark-other-window',
+;;    `bmkp-previous-file-bookmark-other-window-repeat',
+;;    `bmkp-previous-file-bookmark-repeat',
+;;    `bmkp-previous-gnus-bookmark',
+;;    `bmkp-previous-gnus-bookmark-other-window',
+;;    `bmkp-previous-gnus-bookmark-other-window-repeat',
+;;    `bmkp-previous-gnus-bookmark-repeat',
+;;    `bmkp-previous-info-bookmark',
+;;    `bmkp-previous-info-bookmark-other-window',
+;;    `bmkp-previous-info-bookmark-other-window-repeat',
+;;    `bmkp-previous-info-bookmark-repeat',
+;;    `bmkp-previous-lighted-bookmark',
+;;    `bmkp-previous-lighted-bookmark-other-window',
+;;    `bmkp-previous-lighted-bookmark-other-window-repeat',
+;;    `bmkp-previous-lighted-bookmark-repeat',
+;;    `bmkp-previous-local-file-bookmark',
+;;    `bmkp-previous-local-file-bookmark-other-window',
+;;    `bmkp-previous-local-file-bookmark-other-window-repeat',
+;;    `bmkp-previous-local-file-bookmark-repeat',
+;;    `bmkp-previous-man-bookmark',
+;;    `bmkp-previous-man-bookmark-other-window',
+;;    `bmkp-previous-man-bookmark-other-window-repeat',
+;;    `bmkp-previous-man-bookmark-repeat',
+;;    `bmkp-previous-non-file-bookmark',
+;;    `bmkp-previous-non-file-bookmark-other-window',
+;;    `bmkp-previous-non-file-bookmark-other-window-repeat',
+;;    `bmkp-previous-non-file-bookmark-repeat',
+;;    `bmkp-previous-remote-file-bookmark',
+;;    `bmkp-previous-remote-file-bookmark-other-window',
+;;    `bmkp-previous-remote-file-bookmark-other-window-repeat',
+;;    `bmkp-previous-remote-file-bookmark-repeat',
+;;    `bmkp-previous-specific-buffers-bookmark',
+;;    `bmkp-previous-specific-buffers-bookmark-other-window',
+;;    `bmkp-previous-specific-buffers-bookmark-other-window-repeat',
+;;    `bmkp-previous-specific-buffers-bookmark-repeat',
+;;    `bmkp-previous-specific-files-bookmark',
+;;    `bmkp-previous-specific-files-bookmark-other-window',
+;;    `bmkp-previous-specific-files-bookmark-other-window-repeat',
+;;    `bmkp-previous-specific-files-bookmark-repeat',
+;;    `bmkp-previous-variable-list-bookmark',
+;;    `bmkp-previous-variable-list-bookmark-other-window',
+;;    `bmkp-previous-variable-list-bookmark-other-window-repeat',
+;;    `bmkp-previous-variable-list-bookmark-repeat',
+;;    `bmkp-previous-url-bookmark',
+;;    `bmkp-previous-url-bookmark-other-window',
+;;    `bmkp-previous-url-bookmark-other-window-repeat',
+;;    `bmkp-previous-url-bookmark-repeat',
+;;    `bmkp-previous-bookmark-w32',
+;;    `bmkp-previous-bookmark-w32-other-window',
+;;    `bmkp-previous-bookmark-w32-other-window-repeat',
+;;    `bmkp-previous-bookmark-w32-repeat',
+;;    `bmkp-purge-notags-autofiles', `bmkp-read-bookmark-for-type',
+;;    `bmkp-region-jump',
+;;    `bmkp-region-jump-narrow-indirect-other-window',
+;;    `bmkp-region-jump-other-window', `bmkp-remote-file-jump',
+;;    `bmkp-remote-file-jump-other-window',
+;;    `bmkp-remote-non-dir-file-jump',
+;;    `bmkp-temote-non-dir-file-jump-other-window',
+;;    `bmkp-remove-all-tags', `bmkp-remove-tags',
+;;    `bmkp-remove-tags-from-all', `bmkp-rename-tag',
+;;    `bmkp-retrieve-icicle-search-hits',
+;;    `bmkp-retrieve-more-icicle-search-hits',
+;;    `bmkp-revert-bookmark-file',
+;;    `bmkp-save-bookmarks-this-file/buffer',
+;;    `bmkp-save-menu-list-state', `bmkp-send-bug-report',
+;;    `bmkp-set-autonamed-bookmark',
+;;    `bmkp-set-autonamed-bookmark-at-line',
+;;    `bmkp-set-autonamed-regexp-buffer',
+;;    `bmkp-set-autonamed-regexp-region',
+;;    `bmkp-set-bookmark-file-bookmark', `bmkp-set-desktop-bookmark',
+;;    `bmkp-set-dired-bookmark-for-files',
+;;    `bmkp-set-eww-bookmark-here' (Emacs 25+),
+;;    `bmkp-set-grep-command-bookmark' (Emacs 26+),
+;;    `bmkp-set-icicle-search-hits-bookmark',
+;;    `bmkp-set-info-bookmark-with-node-name' (Emacs 22+),
+;;    `bmkp-set-izones-bookmark', `bmkp-set-kmacro-bookmark' (Emacs
+;;    22+), `bmkp-set-kmacro-list-bookmark' (Emacs 22+),
+;;    `bmkp-set-sequence-bookmark', `bmkp-set-snippet-bookmark',
+;;    `bmkp-set-tag-value', `bmkp-set-tag-value-for-navlist',
+;;    `bmkp-set-variable-list-bookmark',
+;;    `bmkp-show-this-annotation-read-only',
+;;    `bmkp-snippet-to-kill-ring', `bmkp-some-tags-jump',
+;;    `bmkp-some-tags-jump-other-window',
+;;    `bmkp-some-tags-regexp-jump',
+;;    `bmkp-some-tags-regexp-jump-other-window',
+;;    `bmkp-specific-buffers-jump',
+;;    `bmkp-specific-buffers-jump-other-window',
+;;    `bmkp-specific-files-jump',
+;;    `bmkp-specific-files-jump-other-window', `bmkp-store-org-link'
+;;    (Emacs 24.4+), `bmkp-switch-bookmark-file',
+;;    `bmkp-switch-bookmark-file-create',
+;;    `bmkp-switch-to-bookmark-file-this-file/buffer',
+;;    `bmkp-switch-to-last-bookmark-file', `bmkp-tag-a-file',
+;;    `bmkp-temporary-bookmarking-mode', `bmkp-temporary-jump',
+;;    `bmkp-temporary-jump-other-window',
+;;    `bmkp-this-buffer-bmenu-list', `bmkp-this-buffer-jump',
+;;    `bmkp-this-buffer-jump-other-window',
+;;    `bmkp-this-file-bmenu-list', `bmkp-this-file/buffer-bmenu-list',
+;;    `bmkp-toggle-autonamed-bookmark-set/delete',
+;;    `bmkp-toggle-autotemp-on-set',
+;;    `bmkp-toggle-bookmark-set-refreshes',
+;;    `bmkp-toggle-eww-auto-type' (Emacs 25+),
+;;    `bmkp-toggle-info-auto-type' (Emacs 22+),
+;;    `bmkp-toggle-saving-bookmark-file',
+;;    `bmkp-toggle-saving-menu-list-state',
+;;    `bmkp-toggle-temporary-bookmark',
+;;    `bmkp-turn-on-automatic-bookmark-mode' (Emacs 21+),
+;;    `bmkp-types-alist', `bmkp-unomit-all', `bmkp-untag-a-file',
+;;    `bmkp-url-target-set', `bmkp-url-jump',
+;;    `bmkp-url-jump-other-window', `bmkp-variable-list-jump',
+;;    `bmkp-version', `bmkp-visit-external-annotation',
+;;    `bmkp-w32-browser-jump', `bmkp-w3m-jump',
+;;    `bmkp-w3m-jump-other-window',
+;;    `bmkp-wrap-bookmark-with-last-kbd-macro'.
+;;
+;;  User options defined here:
+;;
+;;    `bmkp-annotation-modes-inherit-from', `bmkp-autofile-filecache',
+;;    `bmkp-automatic-bookmark-min-distance',
+;;    `bmkp-automatic-bookmark-mode-delay',
+;;    `bmkp-automatic-bookmark-mode-lighter',
+;;    `bmkp-automatic-bookmark-set-function',
+;;    `bmkp-autoname-bookmark-function', `bmkp-autoname-format',
+;;    `bmkp-autotemp-bookmark-predicates',
+;;    `bmkp-bookmark-name-length-max',
+;;    `bmkp-count-multi-mods-as-one-flag', `bmkp-crosshairs-flag',
+;;    `bmkp-default-bookmark-name',
+;;    `bmkp-default-handlers-for-file-types',
+;;    `bmkp-desktop-default-directory',
+;;    `bmkp-desktop-jump-save-before-flag',
+;;    `bmkp-desktop-no-save-vars', `bmkp-eww-auto-type' (Emacs 25+),
+;;    `bmkp-eww-buffer-renaming' (Emacs 25+),
+;;    `bmkp-eww-generate-buffer-flag' (Emacs 25+),
+;;    `bmkp-eww-replace-keys-flag' (Emacs 25+),
+;;    `bmkp-guess-default-handler-for-file-flag',
+;;    `bmkp-handle-region-function', `bmkp-incremental-filter-delay',
+;;    `bmkp-info-auto-type' (Emacs 22+),
+;;    `bmkp-info-sort-ignores-directories-flag',
+;;    `bmkp-last-as-first-bookmark-file',
+;;    `bmkp-menu-popup-max-length', `bmkp-new-bookmark-default-names',
+;;    `bmkp-other-window-pop-to-flag', `bmkp-prompt-for-tags-flag',
+;;    `bmkp-properties-to-keep', `bmkp-read-bookmark-file-hook',
+;;    `bmkp-region-search-size', `bmkp-save-new-location-flag',
+;;    `bmkp-sequence-jump-display-function',
+;;    `bmkp-show-end-of-region-flag', `bmkp-sort-comparer',
+;;    `bmkp-su-or-sudo-regexp', `bmkp-tags-for-completion',
+;;    `bmkp-temporary-bookmarking-mode',
+;;    `bmkp-temporary-bookmarking-mode-hook',
+;;    `bmkp-temporary-bookmarking-mode-lighter',
+;;    `bmkp-this-file/buffer-cycle-sort-comparer', `bmkp-use-region',
+;;    `bmkp-w3m-allow-multiple-buffers-flag',
+;;    `bmkp-write-bookmark-file-hook'.
+;;
+;;  Non-interactive functions defined here:
+;;
+;;    `bmkext-jump-gnus', `bmkext-jump-man', `bmkext-jump-w3m',
+;;    `bmkext-jump-woman', `bmkp-add-jump-to-list-button',
+;;    `bmkp-all-exif-data', `bmkp-all-tags-alist-only',
+;;    `bmkp-all-tags-regexp-alist-only', `bmkp-alpha-cp',
+;;    `bmkp-alpha-p', `bmkp-annotated-alist-only',
+;;    `bmkp-annotated-bookmark-p', `bmkp-annotated-cp',
+;;    `bmkp-annotation-or-bookmark-description',
+;;    `bmkp-autofile-alist-only', `bmkp-autofile-all-tags-alist-only',
+;;    `bmkp-autofile-all-tags-regexp-alist-only',
+;;    `bmkp-autofile-bookmark-p',
+;;    `bmkp-autofile-some-tags-alist-only',
+;;    `bmkp-autofile-some-tags-regexp-alist-only',
+;;    `bmkp-autoname-bookmark-function-default',
+;;    `bmkp-autonamed-alist-only',
+;;    `bmkp-autonamed-bookmark-for-buffer-p',
+;;    `bmkp-autonamed-bookmark-p',
+;;    `bmkp-autonamed-this-buffer-alist-only',
+;;    `bmkp-autonamed-this-buffer-bookmark-p',
+;;    `bmkp-bookmark-creation-cp', `bmkp-bookmark-data-from-record',
+;;    `bmkp-bookmark-description', `bmkp-bookmark-last-access-cp',
+;;    `bmkp-bookmark-file-alist-only',
+;;    `bmkp-bookmark-file-bookmark-p',
+;;    `bmkp-bookmark-list-alist-only',
+;;    `bmkp-bookmark-list-bookmark-p', `bmkp-bookmark-name-member',
+;;    `bmkp-bookmark-record-from-name', `bmkp-buffer-alist-only',
+;;    `bmkp-buffer-last-access-cp', `bmkp-buffer-names',
+;;    `bmkp-compilation-file+line-at', `bmkp-completing-read-1',
+;;    `bmkp-completing-read-bookmarks',
+;;    `bmkp-completing-read-buffer-name',
+;;    `bmkp-completing-read-file-name', `bmkp-completing-read-lax',
+;;    `bmkp-cp-not', `bmkp-create-variable-list-bookmark',
+;;    `bmkp-current-bookmark-list-state', `bmkp-current-sort-order',
+;;    `bmkp-cycle-1', `bmkp-default-bookmark-file',
+;;    `bmkp-default-bookmark-name', `bmkp-default-handler-for-file',
+;;    `bmkp-default-handler-user', `bmkp-delete-autonamed-no-confirm',
+;;    `bmkp-delete-autonamed-this-buffer-no-confirm',
+;;    `bmkp-delete-bookmark-name-from-list',
+;;    `bmkp-delete-temporary-no-confirm', `bmkp-desktop-alist-only',
+;;    `bmkp-desktop-bookmark-p',
+;;    `bmkp-desktop-file-p',`bmkp-desktop-kill', `bmkp-desktop-save',
+;;    `bmkp-desktop-save-as-last', `bmkp-dired-alist-only',
+;;    `bmkp-dired-bookmark-p', `bmkp-dired-remember-*-marks',
+;;    `bmkp-dired-subdirs', `bmkp-dired-this-dir-alist-only',
+;;    `bmkp-dired-wildcards-alist-only',
+;;    `bmkp-dired-this-dir-bookmark-p',
+;;    `bmkp-dired-wildcards-bookmark-p',
+;;    `bmkp-edit-bookmark-record-mode',
+;;    `bmkp-edit-bookmark-records-mode', `bmkp-edit-tags-mode',
+;;    `bmkp-end-position-post-context',
+;;    `bmkp-end-position-pre-context', `bmkp-every',
+;;    `bmkp-eww-alist-only' (Emacs 25+), `bmkp-eww-bookmark-p' (Emacs
+;;    25+), `bmkp-eww-cp' (Emacs 25+), `bmkp-eww-new-buffer-name'
+;;    (Emacs 25+), `bmkp-eww-rename-buffer' (Emacs 25+),
+;;    `bmkp-eww-title' (Emacs 25+), `bmkp-eww-url' (Emacs 25+),
+;;    `bmkp-ffap-guesser', `bmkp-file-alist-only',
+;;    `bmkp-file-all-tags-alist-only',
+;;    `bmkp-file-all-tags-regexp-alist-only', `bmkp-file-alpha-cp',
+;;    `bmkp-file-attribute-0-cp', `bmkp-file-attribute-1-cp',
+;;    `bmkp-file-attribute-2-cp', `bmkp-file-attribute-3-cp',
+;;    `bmkp-file-attribute-4-cp', `bmkp-file-attribute-5-cp',
+;;    `bmkp-file-attribute-6-cp', `bmkp-file-attribute-7-cp',
+;;    `bmkp-file-attribute-8-cp', `bmkp-file-attribute-9-cp',
+;;    `bmkp-file-attribute-10-cp', `bmkp-file-attribute-11-cp',
+;;    `bmkp-file-bookmark-p', `bmkp-file-names', `bmkp-file-remote-p',
+;;    `bmkp-file-some-tags-alist-only',
+;;    `bmkp-file-some-tags-regexp-alist-only',
+;;    `bmkp-file-this-dir-alist-only',
+;;    `bmkp-file-this-dir-all-tags-alist-only',
+;;    `bmkp-file-this-dir-all-tags-regexp-alist-only',
+;;    `bmkp-file-this-dir-bookmark-p',
+;;    `bmkp-file-this-dir-some-tags-alist-only',
+;;    `bmkp-file-this-dir-some-tags-regexp-alist-only',
+;;    `bmkp-find-tag-default-as-regexp' (Emacs 22-24.2),
+;;    `bmkp-flagged-bookmark-p', `bmkp-flagged-cp', `bmkp-float-time',
+;;    `bmkp-format-spec', `bmkp-full-tag', `bmkp-function-alist-only',
+;;    `bmkp-function-bookmark-p', `bmkp-get-autofile-bookmark',
+;;    `bmkp-get-bookmark', `bmkp-get-bookmark-in-alist',
+;;    `bmkp-get-buffer-name', `bmkp-get-end-position',
+;;    `bmkp-get-tag-value', `bmkp-get-tags', `bmkp-get-visit-time',
+;;    `bmkp-get-visits-count', `bmkp-gnus-alist-only',
+;;    `bmkp-gnus-bookmark-p', `bmkp-gnus-cp', `bmkp-goto-position',
+;;    `bmkp-handle-region-default',
+;;    `bmkp-handle-region+narrow-indirect', `bmkp-handler-cp',
+;;    `bmkp-handler-pred', `bmkp-has-tag-p',
+;;    `bmkp-icicles-search-hits-alist-only',
+;;    `bmkp-icicles-search-hits-bookmark-p', `bmkp-image-alist-only',
+;;    `bmkp-image-bookmark-p', `bmkp-info-alist-only',
+;;    `bmkp-info-bookmark-p', `bmkp-info-node-name-cp',
+;;    `bmkp-info-position-cp', `bmkp-isearch-bookmarks' (Emacs 23+),
+;;    `bmkp-isearch-bookmarks-regexp' (Emacs 23+),
+;;    `bmkp-isearch-next-bookmark-buffer' (Emacs 23+), `bmkp-jump-1',
+;;    `bmkp-jump-bookmark-file', `bmkp-jump-bookmark-list',
+;;    `bmkp-jump-desktop', `bmkp-jump-dired', `bmkp-jump-eww' (Emacs
+;;    25+), `bmkp-jump-function', `bmkp-jump-gnus',
+;;    `bmkp-jump-icicle-search-hits', `bmkp-jump-kmacro-list' (Emacs
+;;    22+), `bmkp-jump-man', `bmkp-jump-sequence',
+;;    `bmkp-jump-snippet', `bmkp-jump-url-browse',
+;;    `bmkp-jump-variable-list', `bmkp-jump-w3m',
+;;    `bmkp-jump-w3m-new-buffer', `bmkp-jump-w3m-new-buffer',
+;;    `bmkp-jump-w3m-only-one-buffer',
+;;    `bmkp-jump-w3m-only-one-buffer', `bmkp-jump-woman',
+;;    `bmkp-kmacro-list-bookmark-p',
+;;    `bmkp-last-specific-buffer-alist-only',
+;;    `bmkp-last-specific-buffer-p',
+;;    `bmkp-last-specific-file-alist-only',
+;;    `bmkp-last-specific-file-p', `bmkp-list-position',
+;;    `bmkp-local-directory-bookmark-p',
+;;    `bmkp-local-file-accessed-more-recently-cp',
+;;    `bmkp-local-file-alist-only', `bmkp-local-file-bookmark-p',
+;;    `bmkp-local-file-size-cp', `bmkp-local-file-type-cp',
+;;    `bmkp-local-non-dir-file-alist-only',
+;;    `bmkp-local-non-dir-file-bookmark-p',
+;;    `bmkp-local-file-updated-more-recently-cp',
+;;    `bmkp-make-bookmark-file-record',
+;;    `bmkp-make-bookmark-list-record', `bmkp-make-desktop-record',
+;;    `bmkp-make-dired-record', `bmkp-make-eww-record' (Emacs 25+),
+;;    `bmkp-make-gnus-record', `bmkp-make-icicle-search-hits-record',
+;;    `bmkp-make-kmacro-list-record' (Emacs 22+),
+;;    `bmkp-make-man-record', `bmkp-make-obsolete',
+;;    `bmkp-make-obsolete-variable', `bmkp-make-plain-predicate',
+;;    `bmkp-make-record-for-target-file', `bmkp-make-sequence-record',
+;;    `bmkp-make-url-browse-record', `bmkp-make-variable-list-record',
+;;    `bmkp-make-w3m-record', `bmkp-make-woman-record' (Emacs 21+),
+;;    `bmkp-man-alist-only', `bmkp-man-bookmark-p',
+;;    `bmkp-marked-bookmark-p', `bmkp-marked-bookmarks-only',
+;;    `bmkp-marked-cp', `bmkp-maybe-save-bookmarks',
+;;    `bmkp-modified-bookmark-p', `bmkp-modified-cp',
+;;    `bmkp-msg-about-sort-order', `bmkp-multi-sort',
+;;    `bmkp-names-same-bookmark-p', `bmkp-navlist-bookmark-p',
+;;    `bmkp-new-bookmark-default-names',
+;;    `bmkp-non-autonamed-alist-only', `bmkp-non-dir-file-alist-only',
+;;    `bmkp-non-dir-file-bookmark-p', `bmkp-non-file-alist-only',
+;;    `bmkp-non-file-bookmark-p', `bmkp-non-invokable-alist-only',
+;;    `bmkp-non-invokable-bookmark-p',
+;;    `bmkp-not-near-other-automatic-bmks', `bmkp-omitted-alist-only',
+;;    `bmkp-orphaned-file-alist-only',
+;;    `bmkp-orphaned-file-bookmark-p',
+;;    `bmkp-orphaned-local-file-alist-only',
+;;    `bmkp-orphaned-local-file-bookmark-p',
+;;    `bmkp-orphaned-remote-file-alist-only',
+;;    `bmkp-orphaned-remote-file-bookmark-p',
+;;    `bmkp-pop-to-readable-marker', `bmkp-position-after-whitespace',
+;;    `bmkp-position-before-whitespace', `bmkp-position-cp',
+;;    `bmkp-position-post-context',
+;;    `bmkp-position-post-context-region',
+;;    `bmkp-position-pre-context', `bmkp-position-pre-context-region',
+;;    `bmkp-printable-vars+vals', `bmkp-propertize',
+;;    `bmkp-readable-p', `bmkp-read-bookmark-file-default',
+;;    `bmkp-read-bookmark-file-name', `bmkp-read-buffers',
+;;    `bmkp-read-files', `bmkp-read-from-whole-string',
+;;    `bmkp-read-regexp', `bmkp-read-tag-completing',
+;;    `bmkp-read-tags', `bmkp-read-tags-completing',
+;;    `bmkp-read-variable', `bmkp-read-variables-completing',
+;;    `bmkp-record-visit', `bmkp-refresh-latest-bookmark-list',
+;;    `bmkp-refresh-menu-list', `bmkp-refresh/rebuild-menu-list',
+;;    `bmkp-regexp-filtered-annotation-alist-only',
+;;    `bmkp-regexp-filtered-bookmark-name-alist-only',
+;;    `bmkp-regexp-filtered-file-name-alist-only',
+;;    `bmkp-regexp-filtered-tags-alist-only',
+;;    `bmkp-region-alist-only', `bmkp-region-bookmark-p',
+;;    `bmkp-remote-file-alist-only', `bmkp-remote-file-bookmark-p',
+;;    `bmkp-remote-non-dir-file-alist-only',
+;;    `bmkp-remote-non-dir-file-bookmark-p', `bmkp-remove-dups',
+;;    `bmkp-remove-if', `bmkp-remove-if-not', `bmkp-remove-omitted',
+;;    `bmkp-rename-for-marked-and-omitted-lists',
+;;    `bmkp-repeat-command', `bmkp-replace-existing-bookmark',
+;;    `bmkp-reset-bmkp-store-org-link-checking-p' (Emacs 24.4+),
+;;    `bmkp-retrieve-icicle-search-hits-1',
+;;    `bmkp-root-or-sudo-logged-p', `bmkp-same-creation-time-p',
+;;    `bmkp-same-file-p', `bmkp-save-new-region-location',
+;;    `bmkp-select-buffer-other-window', `bmkp-sequence-alist-only',
+;;    `bmkp-sequence-bookmark-p', `bmkp-set-automatic-bookmark',
+;;    `bmkp-set-tag-value-for-bookmarks', `bmkp-set-union',
+;;    `bmkp-snippet-alist-only', `bmkp-snippet-bookmark-p',
+;;    `bmkp-some', `bmkp-some-marked-p', `bmkp-some-tags-alist-only',
+;;    `bmkp-some-tags-regexp-alist-only', `bmkp-some-unmarked-p',
+;;    `bmkp-sorting-description', `bmkp-sort-omit', `bmkp-sound-jump',
+;;    `bmkp-specific-buffers-alist-only',
+;;    `bmkp-specific-files-alist-only', `bmkp-store-org-link-1',
+;;    `bmkp-string-less-case-fold-p', `bmkp-tagged-alist-only',
+;;    `bmkp-tagged-bookmark-p', `bmkp-tagged-cp', `bmkp-tag-name',
+;;    `bmkp-tags-in-bookmark-file', `bmkp-tags-list',
+;;    `bmkp-temporary-alist-only', `bmkp-temporary-bookmark-p',
+;;    `bmkp-thing-at-point', `bmkp-this-buffer-alist-only',
+;;    `bmkp-this-buffer-p', `bmkp-this-file-alist-only',
+;;    `bmkp-this-file/buffer-alist-only', `bmkp-this-file-p',
+;;    `bmkp-unmarked-bookmarks-only', `bmkp-unpropertized-string',
+;;    `bmkp-untagged-alist-only', `bmkp-upcase',
+;;    `bmkp-update-autonamed-bookmark', `bmkp-url-alist-only',
+;;    `bmkp-url-bookmark-p', `bmkp-url-browse-alist-only',
+;;    `bmkp-url-browse-bookmark-p', `bmkp-url-cp',
+;;    `bmkp-variable-list-alist-only',
+;;    `bmkp-variable-list-bookmark-p', `bmkp-visited-more-cp',
+;;    `bmkp-w3m-alist-only', `bmkp-w3m-bookmark-p', `bmkp-w3m-cp',
+;;    `bmkp-w3m-set-new-buffer-name',
+;;    `bmkp-write-alist-bookmarks-to-file'.
+;;
+;;  Internal variables defined here:
+;;
+;;    `bmkp-after-set-hook', `bmkp-autofile-history',
+;;    `bmkp-automatic-bookmark-mode-timer',
+;;    `bmkp-automatic-bookmarks', `bmkp-autonamed-history',
+;;    `bmkp-autotemp-all-when-set-p', `bmkp-before-jump-hook',
+;;    `bmkp-bookmark-file-history', `bmkp-bookmark-list-history',
+;;    `bmkp-bookmark-set-confirms-overwrite-p',
+;;    `bmkp-buffer-bookmark-p', `bmkp-current-bookmark-file',
+;;    `bmkp-current-nav-bookmark', `bmkp-desktop-current-file',
+;;    `bmkp-desktop-history', `bmkp-dired-history',
+;;    `bmkp-edit-bookmark-record-mode-map',
+;;    `bmkp-edit-bookmark-records-mode-map',
+;;    `bmkp-edit-bookmark-records-number', `bmkp-edit-tags-mode-map',
+;;    `bmkp-eww-history' (Emacs 25+), `bmkp-eww-jumping-p' (Emacs
+;;    25+), `bmkp-eww-new-buf-name' (Emacs 25+),
+;;    `bmkp-file-bookmark-handlers', `bmkp-file-history',
+;;    `bmkp-gnus-history', `bmkp-icicles-search-hits-retrieve-more',
+;;    `bmkp-image-history', `bmkp-info-history',
+;;    `bmkp-isearch-bookmarks' (Emacs 23+),
+;;    `bmkp-jump-display-function', `bmkp-jump-other-window-map',
+;;    `bmkp-last-bmenu-state-file', `bmkp-last-bookmark-file',
+;;    `bmkp-last-save-flag-value', `bmkp-last-specific-buffer',
+;;    `bmkp-last-specific-file', `bmkp-latest-bookmark-alist',
+;;    `bmkp-local-file-history', `bmkp-man-history',
+;;    `bmkp-modified-bookmarks', `bmkp-nav-alist',
+;;    `bmkp-non-file-filename', `bmkp-non-file-history',
+;;    `bmkp-region-history', `bmkp-remote-file-history',
+;;    `bmkp-return-buffer', `bmkp-reverse-multi-sort-p',
+;;    `bmkp-reverse-sort-p', `bmkp-snippet-history',
+;;    `bmkp-sorted-alist', `bmkp-specific-buffers-history',
+;;    `bmkp-specific-files-history', `bmkp-store-org-link-checking-p',
+;;    `bmkp-tag-history', `bmkp-tags-alist', `bmkp-temporary-history',
+;;    `bmkp-url-history', `bmkp-use-w32-browser-p',
+;;    `bmkp-variable-list-history', `bmkp-version-number',
+;;    `bmkp-w3m-history'.
+;;
+;;
+;;  ***** NOTE: The following commands defined in `bookmark.el'
+;;              have been REDEFINED HERE:
+;;
+;;    `bookmark-default-annotation-text', `bookmark-delete',
+;;    `bookmark-edit-annotation-mode', `bookmark-insert',
+;;    `bookmark-insert-annotation',
+;;    `bookmark-insert-current-bookmark', `bookmark-insert-location',
+;;    `bookmark-jump', `bookmark-jump-other-frame',
+;;    `bookmark-jump-other-window', `bookmark-load',
+;;    `bookmark-relocate', `bookmark-rename', `bookmark-save',
+;;    `bookmark-send-edited-annotation', `bookmark-set',
+;;    `bookmark-set-name', `bookmark-yank-word'.
+;;
+;;
+;;  ***** NOTE: The following user options defined in `bookmark.el'
+;;              have been REDEFINED HERE:
+;;
+;;    `bookmark-automatically-show-annotations', `bookmark-sort-flag'
+;;    (document non-use), `bookmark-version-control'.
+;;
+;;
+;;  ***** NOTE: The following non-interactive functions defined in
+;;              `bookmark.el' have been REDEFINED HERE:
+;;
+;;    `bookmark--jump-via', `bookmark-alist-from-buffer',
+;;    `bookmark-all-names', `bookmark-completing-read',
+;;    `bookmark-default-handler', `bookmark-edit-annotation' (command
+;;    here), `bookmark-exit-hook-internal', `bookmark-get-bookmark',
+;;    `bookmark-get-bookmark-record' (Emacs 20-22),
+;;    `bookmark-get-handler' (Emacs 20-22),
+;;    `bookmark-handle-bookmark', `bookmark-import-new-list',
+;;    `bookmark-jump-noselect' (Emacs 20-22), `bookmark-location',
+;;    `bookmark-make-record', `bookmark-make-record-default',
+;;    `bookmark-maybe-load-default-file', `bookmark-maybe-rename',
+;;    `bookmark-prop-get' (Emacs 20-22), `bookmark-prop-set',
+;;    `bookmark-show-annotation' (command here),
+;;    `bookmark-show-all-annotations' (command here), `bookmark-store'
+;;    (Emacs 20-22), `bookmark-write-file'.
+;;
+;;
+;;  ***** NOTE: The following internal variables defined in
+;;              `bookmark.el' have been REDEFINED HERE:
+;;
+;;    `bookmark-alist' (doc string only),
+;;    `bookmark-make-record-function' (Emacs 20-22),
+;;    `bookmarks-already-loaded' (doc string only).
+;;
+;;
+;;  ***** NOTE: The following function defined in `info.el'
+;;              has been REDEFINED HERE:
+;;
+;;    `Info-bookmark-make-record' (Emacs 20-22).
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;
+
+(unless (fboundp 'file-remote-p) (require 'ffap)) ;; ffap-file-remote-p
+(eval-when-compile (require 'gnus)) ;; mail-header-id (really in `nnheader.el')
+(eval-when-compile (require 'gnus-sum)) ;; gnus-summary-article-header
+(eval-when-compile (require 'cl)) ;; case, multiple-value-bind, typecase (plus, for Emacs 20: dolist, push)
+
+(when (and (require 'thingatpt+ nil t) ;; (no error if not found):
+           (fboundp 'tap-put-thing-at-point-props)) ; >= 2012-08-21
+  (tap-define-aliases-wo-prefix)
+  (tap-put-thing-at-point-props))
+;; region-or-non-nil-symbol-name-nearest-point, symbol-nearest-point
+
+(when (> emacs-major-version 21) (require 'font-lock+ nil t)) ;; font-lock-ignore (text property)
+
+(require 'bookmark)
+;; bookmark-alist, bookmark-alist-modification-count, bookmark-annotation-name,
+;; bookmark-automatically-show-annotations, bookmark-bmenu-bookmark,
+;; bookmark-bmenu-surreptitiously-rebuild-list, bookmark-buffer-file-name, bookmark-buffer-name,
+;; bookmark-completion-ignore-case, bookmark-current-bookmark, bookmark-default-file,
+;; bookmark-edit-annotation, bookmark-get-annotation, bookmark-get-bookmark, bookmark-get-bookmark-record,
+;; bookmark-get-filename, bookmark-get-front-context-string, bookmark-get-handler, bookmark-get-position,
+;; bookmark-get-rear-context-string, bookmark-insert-file-format-version-stamp, bookmark-kill-line,
+;; bookmark-make-record, bookmark-maybe-historicize-string, bookmark-maybe-upgrade-file-format,
+;; bookmark-menu-popup-paned-menu, bookmark-name-from-full-record, bookmark-name-from-record,
+;; bookmark-popup-menu-and-apply-function, bookmark-prop-get, bookmark-save-flag, bookmark-search-size,
+;; bookmark-set-annotation, bookmark-set-filename, bookmark-set-position, bookmark-time-to-save-p,
+;; bookmark-use-annotations, bookmark-yank-point
+
+
+;; Some general Renamings.
+;;
+;; 1. Fix incompatibility introduced by gratuitous Emacs name change.
+;;
+(cond ((and (fboundp 'bookmark-name-from-record)  (not (fboundp 'bookmark-name-from-full-record)))
+       (defalias 'bookmark-name-from-full-record 'bookmark-name-from-record))
+      ((and (fboundp 'bookmark-name-from-full-record)  (not (fboundp 'bookmark-name-from-record)))
+       (defalias 'bookmark-name-from-record 'bookmark-name-from-full-record)))
+
+;; 2. The vanilla name of the first is misleading, as it returns only the cdr of the record.
+;;    The second is for consistency.
+;;
+(defalias 'bmkp-bookmark-data-from-record 'bookmark-get-bookmark-record)
+(defalias 'bmkp-bookmark-name-from-record 'bookmark-name-from-full-record)
+
+;; 3. Do these up front.  Emacs 23 made incompatible change to require all args.
+;;
+(defun bmkp-make-obsolete (obsolete-name current-name &optional when)
+  "Same as `make-obsolete', but usable also for Emacs prior to Emacs 23."
+  (if (< emacs-major-version 23)
+      (make-obsolete obsolete-name current-name)
+    (make-obsolete obsolete-name current-name when)))
+
+(defun bmkp-make-obsolete-variable (obsolete-name current-name &optional when access-type)
+  "Same as `make-obsolete-variable', but usable also for Emacs prior to Emacs 23."
+  (if (< emacs-major-version 23)
+      (make-obsolete-variable obsolete-name current-name)
+    (make-obsolete-variable obsolete-name current-name when)))
+
+
+
+(eval-when-compile
+ (or (condition-case nil
+         (load-library "bookmark+-mac") ; Use load-library to ensure latest .elc.
+       (error nil))
+     (require 'bookmark+-mac)))         ; Require, so can load separately if not on `load-path'.
+;; bmkp-define-cycle-command, bmkp-define-file-sort-predicate, bmkp-define-next+prev-cycle-commands,
+;; bmkp-with-help-window, bmkp-with-output-to-plain-temp-buffer
+
+(eval-when-compile (require 'bookmark+-bmu))
+;; bmkp-bmenu-before-hide-marked-alist, bmkp-bmenu-before-hide-unmarked-alist, bmkp-bmenu-commands-file,
+;; bmkp-replace-regexp-in-string, bmkp-bmenu-filter-function, bmkp-bmenu-filter-pattern,
+;; bmkp-bmenu-first-time-p, bmkp-flagged-bookmarks, bmkp-bmenu-goto-bookmark-named,
+;; bmkp-bmenu-marked-bookmarks, bmkp-bmenu-omitted-bookmarks, bmkp-bmenu-refresh-menu-list,
+;; bmkp-bmenu-show-all, bmkp-bmenu-state-file, bmkp-bmenu-title, bmkp-looking-at-p,
+;; bmkp-maybe-unpropertize-bookmark-names, bmkp-sort-orders-alist, bookmark-bmenu-toggle-filenames
+
+
+;; (eval-when-compile (require 'bookmark+-lit nil t))
+;; bmkp-light-bookmark, bmkp-light-bookmarks, bmkp-light-this-buffer
+
+
+;; For the redefinition of `bookmark-get-bookmark'.
+(provide 'bookmark+-1)                  ; Ensure this library is loaded before we compile it.
+(require 'bookmark+-1)                  ; So be sure to put this library in your `load-path' before
+                                        ; trying to byte-compile it.
+
+;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Quiet the byte-compiler
+
+(defvar bmkp-auto-light-when-set)       ; In `bookmark+-lit.el'
+(defvar bmkp-auto-light-when-jump)      ; In `bookmark+-lit.el'
+(defvar bmkp-bmenu-buffer)              ; In `bookmark+.el'
+(defvar bmkp-edit-bookmark-record-mode-map) ; Here, via `define-derived-mode'
+(defvar bmkp-edit-bookmark-records-mode-map) ; Here, via `define-derived-mode'
+(defvar bmkp-edit-tags-mode-map)        ; Here, via `define-derived-mode'
+(defvar bmkp-eww-auto-type)             ; Here (Emacs 25+)
+(defvar bmkp-eww-buffer-renaming)       ; Here (Emacs 25+)
+(defvar bmkp-eww-generate-buffer-flag)  ; Here (Emacs 25+)
+(defvar bmkp-eww-jumping-p)             ; Here (Emacs 25+)
+(defvar bmkp-eww-new-buf-name)          ; Here (Emacs 25+)
+(defvar bmkp-eww-replace-keys-flag)     ; Here (Emacs 25+)
+(defvar bmkp-info-auto-type)            ; Here (Emacs 22+)
+(defvar bmkp-light-priorities)          ; In `bookmark+-lit.el'
+(defvar bmkp-temporary-bookmarking-mode) ;  Here
+(defvar bmkp-global-automatic-bookmark-mode) ; Here, via `define-globalized-minor-mode'
+(defvar bookmark-current-point)         ; In `bookmark.el', but not in Emacs 23+
+(defvar bookmark-edit-annotation-text-func) ; In `bookmark.el'
+(defvar bookmark-file-coding-system)    ; In `bookmark.el' (Emacs 25.2+)
+(defvar bookmark-read-annotation-text-func) ; In `bookmark.el', but not in Emacs 23+
+(defvar bookmark-make-record-function)  ; In `bookmark.el'
+(defvar desktop-basefilename)           ; In `desktop.el' (Emacs < 22)
+(defvar desktop-base-file-name)         ; In `desktop.el'
+(defvar desktop-buffer-args-list)       ; In `desktop.el'
+(defvar desktop-delay-hook)             ; In `desktop.el'
+(defvar desktop-dirname)                ; In `desktop.el'
+(defvar desktop-file-modtime)           ; In `desktop.el'
+(defvar desktop-globals-to-save)        ; In `desktop.el'
+(defvar desktop-save-mode)              ; In `desktop.el'
+(defvar desktop-save)                   ; In `desktop.el'
+(defvar dired-actual-switches)          ; In `dired.el'
+(defvar dired-buffers)                  ; In `dired.el'
+(defvar dired-directory)                ; In `dired.el'
+(defvar dired-guess-shell-case-fold-search) ; In `dired-x.el'
+(defvar dired-subdir-alist)             ; In `dired.el'
+(defvar eww-data)                       ; In `eww.el' (Emacs 25+)
+(defvar eww-local-regex)                ; In `eww.el' (Emacs 25+)
+(defvar eww-search-prefix)              ; In `eww.el' (Emacs 25+)
+(defvar gnus-article-current)           ; In `gnus-sum.el'
+(defvar icicle-candidate-properties-alist) ; In `icicles-var.el'
+(defvar icicle-completion-candidates)   ; In `icicles-var.el'
+(defvar icicle-mode)                    ; In `icicle-mode.el'
+(defvar icicle-multi-completing-p)      ; In `icicles-var.el'
+(defvar icicle-saved-completion-candidates) ; In `icicles-var.el'
+(defvar icicle-searching-p)             ; In `icicles-var.el'
+(defvar Info-current-node)              ; In `info.el'
+(defvar Info-current-file)              ; In `info.el'
+(defvar kmacro-counter)                 ; In `kmacro.el'
+(defvar kmacro-counter-format-start)    ; In `kmacro.el'
+(defvar kmacro-ring)                    ; In `kmacro.el'
+(defvar Man-arguments)                  ; In `man.el'
+(defvar org-store-link-functions)       ; In `org.el'
+(defvar read-file-name-completion-ignore-case) ; Emacs 23+
+(defvar last-repeatable-command)        ; In `repeat.el'
+(defvar w3m-current-title)              ; In `w3m.el'
+(defvar w3m-current-url)                ; In `w3m.el'
+(defvar w3m-mode-map)                   ; In `w3m.el'
+(defvar zz-izones)                      ; In `zones.el'
+(defvar zz-izones-var)                  ; In `zones.el'
+(defvar woman-last-file-name)           ; In `woman.el'
+ 
+;;(@* "User Options (Customizable)")
+;;; User Options (Customizable) --------------------------------------
+
+;;;###autoload (autoload 'bmkp-autofile-access-invokes-bookmark-flag "bookmark+")
+(defcustom bmkp-autofile-access-invokes-bookmark-flag nil
+  "*Non-nil means invoke the bookmark when you access an autofile.
+That is, if a file has an associated autofile bookmark then functions
+such as `find-file' will automatically jump to the bookmark.  The
+buffer position of an autofile bookmark is not important, but this can
+be useful to update the bookmark data, such as the number of visits.
+
+If you change the option value in Lisp code without using a Customize
+function, then add/remove `bmkp-find-file-invoke-bookmark-if-autofile'
+to/from `find-file-hook'."
+  :set (lambda (sym new-val)
+         (custom-set-default sym new-val)
+         (let ((hook-var  (if (< emacs-major-version 22) 'find-file-hooks 'find-file-hook)))
+           (if bmkp-autofile-access-invokes-bookmark-flag
+               (add-hook hook-var 'bmkp-find-file-invoke-bookmark-if-autofile)
+             (remove-hook hook-var 'bmkp-find-file-invoke-bookmark-if-autofile))))
+  :type 'boolean :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-autofile-filecache "bookmark+")
+(defcustom bmkp-autofile-filecache 'cache-only
+  "*Whether Emacs filecache commands create/set an autofile bookmark.
+The possible values:
+`autofile+cache' - Whenever a file is added to the file cache, also
+                   create/set an autofile bookmark for the file.
+`autofile-only'  - Create/set an autofile instead of caching the file.
+`cache-only'     - Add the file to the file cache.  No autofile."
+  :type '(choice
+          (const :tag "Create/set an autofile bookmark instead of adding to file cache"  autofile-only)
+          (const :tag "Create/set an autofile bookmark and add to file cache"            autofile+cache)
+          (const :tag "Add to file cache only - do not create/set an autofile bookmark"  cache-only))
+  :group 'bookmark-plus)
+
+
+;; We do not use `define-obsolete-variable-alias' so that byte-compilation in older Emacs
+;; works for newer Emacs too.
+(when (fboundp 'defvaralias)            ; Emacs 22+
+  (defvaralias 'bmkp-auto-idle-bookmark-min-distance 'bmkp-automatic-bookmark-min-distance)
+  (bmkp-make-obsolete-variable 'bmkp-auto-idle-bookmark-min-distance 'bmkp-automatic-bookmark-min-distance
+                               "2021-08-18"))
+
+;;;###autoload (autoload 'bmkp-automatic-bookmark-min-distance "bookmark+")
+(defcustom bmkp-automatic-bookmark-min-distance 1000
+  "*Minimum number of chars between automatic bookmark positions.
+Automatic bookmarking is done by `bmkp-automatic-bookmark-mode'."
+  :type '(choice
+          (const   :tag "No minumum distance" nil)
+          (integer :tag "At least this many chars" :value 1000))
+  :group 'bookmark-plus)
+
+;; Emacs 20 only.
+;;
+;; (Don't bother aliasing the old name, for Emacs 20.)
+;;
+;;;###autoload (autoload 'bmkp-automatic-bookmark-mode "bookmark+")
+(unless (fboundp 'define-minor-mode)
+  (defcustom bmkp-automatic-bookmark-mode nil
+    "*Non-nil means that bookmarks are created periodically automatically.
+Setting this variable directly does not take effect;
+use either \\[customize] or command `bmkp-automatic-bookmark-mode'."
+    :set        (lambda (symbol value) (bmkp-automatic-bookmark-mode (if value 1 -1)))
+    :initialize 'custom-initialize-default
+    :type 'boolean :group 'bookmark-plus :require 'bookmark+))
+
+
+;; We do not use `define-obsolete-variable-alias' so that byte-compilation in older Emacs
+;; works for newer Emacs too.
+(when (fboundp 'defvaralias)            ; Emacs 22+
+  (defvaralias 'bmkp-auto-idle-bookmark-mode-delay 'bmkp-automatic-bookmark-mode-delay)
+  (bmkp-make-obsolete-variable 'bmkp-auto-idle-bookmark-mode-delay 'bmkp-automatic-bookmark-mode-delay
+                               "2021-08-18"))
+
+;;;###autoload (autoload 'bmkp-automatic-bookmark-mode-delay "bookmark+")
+(defcustom bmkp-automatic-bookmark-mode-delay 60
+  "*Number of seconds delay before automatically setting a bookmark.
+Automatic bookmarking is done by `bmkp-automatic-bookmark-mode'."
+  :type 'integer :group 'bookmark-plus)
+
+
+;; We do not use `define-obsolete-variable-alias' so that byte-compilation in older Emacs
+;; works for newer Emacs too.
+(when (fboundp 'defvaralias)            ; Emacs 22+
+  (defvaralias 'bmkp-auto-idle-bookmark-mode-lighter 'bmkp-automatic-bookmark-mode-lighter)
+  (bmkp-make-obsolete-variable 'bmkp-auto-idle-bookmark-mode-lighter 'bmkp-automatic-bookmark-mode-lighter
+                               "2021-08-18"))
+
+;;;###autoload (autoload 'bmkp-automatic-bookmark-mode-lighter "bookmark+")
+(defcustom bmkp-automatic-bookmark-mode-lighter " Auto-Bmk"
+  "*Lighter for `bmkp-automatic-bookmark-mode'.
+This string shows in the mode line when `bmkp-automatic-bookmark-mode'
+is enabled.  Set this to nil or \"\" if you do not want any lighter."
+  :type 'string :group 'bookmark-plus)
+
+
+;; We do not use `define-obsolete-variable-alias' so that byte-compilation in older Emacs
+;; works for newer Emacs too.
+(when (fboundp 'defvaralias)            ; Emacs 22+
+  (defvaralias 'bmkp-auto-idle-bookmark-mode-set-function 'bmkp-automatic-bookmark-set-function)
+  (bmkp-make-obsolete-variable 'bmkp-auto-idle-bookmark-mode-set-function
+                               'bmkp-automatic-bookmark-set-function
+                               "2021-08-18"))
+
+;;;###autoload (autoload 'bmkp-automatic-bookmark-set-function "bookmark+")
+(defcustom bmkp-automatic-bookmark-set-function #'bmkp-set-autonamed-bookmark-at-line
+  "*Function used to set an automatic bookmark.
+Used by `bmkp-automatic-bookmark-mode' and `bmkp-set-automatic-bookmark'.
+
+The default value, `bmkp-set-autonamed-bookmark-at-line', sets an
+autonamed bookmark at the start of the current line.  To bookmark the
+current position, so you can have more than one automatic bookmark per
+line, use `bmkp-set-autonamed-bookmark' instead."
+  :type 'function :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-autoname-bookmark-function "bookmark+")
+(defcustom bmkp-autoname-bookmark-function 'bmkp-autoname-bookmark-function-default
+  "*Function to automatically name a bookmark at point (cursor position).
+It should accept a buffer position as its (first) argument.
+The name returned should match the application of
+`bmkp-autoname-format' to the buffer name."
+  :type 'function :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-autoname-format "bookmark+")
+(defcustom bmkp-autoname-format (if (> emacs-major-version 21) "^[0-9]\\{9\\} %B" "^[0-9]+ %B")
+  "*Format string to match an autonamed bookmark name.
+You can use `%B' instead of `%s' to accept the buffer name.  This has
+the advantage that commands and other functions that check for a
+buffer-specific bookmark can tell more accurately whether a bookmark
+name matches the given buffer.  This applies to functions such as
+`bmkp-autonamed-this-buffer-jump' and
+`bmkp-autonamed-this-buffer-bookmark-p'."
+  :type 'string :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-autotemp-bookmark-predicates "bookmark+")
+(defcustom bmkp-autotemp-bookmark-predicates '(bmkp-autonamed-bookmark-p
+                                               bmkp-autonamed-this-buffer-bookmark-p)
+  "*Predicates for bookmarks to be set (created) as temporary bookmarks.
+Each is typically a type predicate, but it can be any function that
+accepts as its (first) argument a bookmark or bookmark name.
+
+These are the predefined type predicates:
+
+`bmkp-annotated-bookmark-p', `bmkp-autofile-bookmark-p',
+`bmkp-autonamed-bookmark-for-buffer-p', `bmkp-autonamed-bookmark-p',
+`bmkp-autonamed-this-buffer-bookmark-p', `bmkp-buffer-bookmark-p',
+`bmkp-bookmark-file-bookmark-p', `bmkp-bookmark-list-bookmark-p',
+`bmkp-desktop-bookmark-p', `bmkp-dired-bookmark-p',
+`bmkp-dired-this-dir-bookmark-p', `bmkp-dired-wildcards-bookmark-p',
+`bmkp-eww-bookmark-p' (Emacs 25+), `bmkp-file-bookmark-p',
+`bmkp-file-remote-p', `bmkp-file-this-dir-bookmark-p',
+`bmkp-flagged-bookmark-p', `bmkp-function-bookmark-p',
+`bmkp-gnus-bookmark-p', `bmkp-icicles-search-hits-bookmark-p',
+`bmkp-image-bookmark-p', `bmkp-info-bookmark-p',
+`bmkp-last-specific-buffer-p', `bmkp-last-specific-file-p',
+`bmkp-local-directory-bookmark-p', `bmkp-local-file-bookmark-p',
+`bmkp-local-non-dir-file-bookmark-p', `bmkp-man-bookmark-p',
+`bmkp-marked-bookmark-p', `bmkp-modified-bookmark-p',
+`bmkp-navlist-bookmark-p', `bmkp-non-dir-file-bookmark-p',
+`bmkp-non-file-bookmark-p', `bmkp-non-invokable-bookmark-p',
+`bmkp-omitted-bookmark-p', `bmkp-orphaned-file-bookmark-p',
+`bmkp-orphaned-local-file-bookmark-p',
+`bmkp-orphaned-remote-file-bookmark-p', `bmkp-region-bookmark-p',
+`bmkp-remote-file-bookmark-p', `bmkp-remote-non-dir-file-bookmark-p',
+`bmkp-sequence-bookmark-p', `bmkp-snippet-bookmark-p',
+`bmkp-temporary-bookmark-p', `bmkp-this-buffer-p', `bmkp-this-file-p',
+`bmkp-url-bookmark-p', `bmkp-url-browse-bookmark-p',
+`bmkp-variable-list-bookmark-p', `bmkp-w3m-bookmark-p'"
+  :type '(repeat symbol) :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-bookmark-name-length-max "bookmark+")
+(defcustom bmkp-bookmark-name-length-max 70
+  "*Max number of chars for default name for a bookmark with a region."
+  :type 'integer :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-count-multi-mods-as-one-flag "bookmark+")
+(defcustom bmkp-count-multi-mods-as-one-flag t
+  "*Non-nil means count multiple modifications as one.
+This is for `bookmark-alist-modification-count'.  Non-nil means that
+when you invoke a command that acts on multiple bookmarks or acts in
+multiple ways on one bookmark, all of changes together count as only
+one modification.  That can prevent automatic saving of your bookmark
+file during the sequence of modifications, so that when the command is
+done you can choose not to save (i.e., to quit) if you like."
+  :type 'boolean :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-crosshairs-flag "bookmark+")
+(defcustom bmkp-crosshairs-flag (> emacs-major-version 21)
+  "*Non-nil means highlight with crosshairs when you visit a bookmark.
+The highlighting is temporary - until your next action.
+You need library `crosshairs.el' for this feature, and you need Emacs
+22 or later.
+
+NOTE: Crosshairs highlighting is shown in the buffer that is current
+after jumping.  If the bookmarked jumped to does not really have an
+associated buffer, for example a bookmark with a handler such as
+`w32-browser' that just invokes a separate, non-Emacs program, then
+the current buffer after jumping will be the buffer before jumping.
+
+If you use this option in Lisp code, you will want to add/remove
+`bmkp-crosshairs-highlight' to/from `bookmark-after-jump-hook'."
+  :set (lambda (sym new-val)
+         (custom-set-default sym new-val)
+         (if (and bmkp-crosshairs-flag  (> emacs-major-version 21)
+                  (condition-case nil (require 'crosshairs nil t) (error nil)))
+             (add-hook 'bookmark-after-jump-hook 'bmkp-crosshairs-highlight)
+           (remove-hook 'bookmark-after-jump-hook 'bmkp-crosshairs-highlight)))
+  :type 'boolean :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-default-bookmark-name "bookmark+")
+(defcustom bmkp-default-bookmark-name 'highlighted
+  "*Default bookmark name preference for accessing existing bookmarks.
+\(The default name for a *new* bookmark is obtained using option
+`bmkp-new-bookmark-default-names'.)
+
+In `*Bookmark List*' use the name of the current line's bookmark.
+Otherwise, if `bookmark+-lit.el' is not loaded then use the name of
+the last-used bookmark in the current file.
+
+Otherwise, use this option to determine the default, by preferring one
+of the following, if available:
+
+* a highlighted bookmark at point
+* the last-used bookmark in the current file"
+  :type '(choice
+          (const :tag "Highlighted bookmark at point"    highlighted)
+          (const :tag "Last used bookmark in same file"  last-used))
+  :group 'bookmark-plus)
+
+
+;; We do not use `define-obsolete-variable-alias' so that byte-compilation in older Emacs
+;; works for newer Emacs too.
+(when (fboundp 'defvaralias)            ; Emacs 22+
+  (defvaralias 'bmkp-default-handler-associations 'bmkp-default-handlers-for-file-types)
+  (bmkp-make-obsolete-variable 'bmkp-default-handler-associations 'bmkp-default-handlers-for-file-types
+                               "2012-02-27"))
+
+;;;###autoload (autoload 'bmkp-default-handlers-for-file-types "bookmark+")
+(defcustom bmkp-default-handlers-for-file-types
+  (and (require 'dired-x)               ; It in turn requires `dired-aux.el'
+       (eval-when-compile (when (< emacs-major-version 21) (require 'cl))) ;; `dolist', for Emacs 20
+       (let ((assns  ()))
+         (dolist (shell-assn  dired-guess-shell-alist-user)
+           (push (cons (car shell-assn)
+                       `(lambda (bmk)
+                         (dired-run-shell-command
+                          (dired-shell-stuff-it ,(cadr shell-assn) (list (bookmark-get-filename bmk))
+                           nil nil))))
+                 assns))
+         assns))
+  "*File associations for bookmark handlers used for indirect bookmarks.
+Each element of the alist is (REGEXP . COMMAND).
+REGEXP matches a file name.
+COMMAND is a sexp that evaluates to either a shell command (a string)
+ or an Emacs function (a symbol or a lambda form).  The shell command
+ or Lisp function must accept a file-name argument.
+
+Example value:
+
+ ((\"\\\\.pdf$\"   . \"AcroRd32.exe\") ; Adobe Acrobat Reader
+  (\"\\\\.ps$\"    . \"gsview32.exe\") ; Ghostview (PostScript viewer)
+  (\"\\\\.html?$\" . browse-url)       ; Use Lisp function `browse-url'
+  (\"\\\\.doc$\"   . w32-browser))     ; Use Lisp function `w32-browser'
+
+When you change this option using Customize, if you want to use a
+literal string as COMMAND then you must double-quote the text:
+\"...\".  (But do not use double-quotes for the REGEXP.)  If you want
+to use a symbol as COMMAND, just type the symbol name (no quotes).
+
+This option is used by `bmkp-default-handler-for-file' to determine
+the default `file-handler' property for a given file bookmark.  If a
+given file name does not match this option, and if
+`bmkp-guess-default-handler-for-file-flag' is non-nil, then
+`bmkp-default-handler-for-file' tries to guess a shell command to use
+in the default handler.  For that it uses `dired-guess-default' and
+\(Emacs 23+ only) mailcap entries, in that order."
+  :type '(alist :key-type
+          regexp :value-type
+          (sexp :tag "Shell command (string) or Emacs function (symbol or lambda form)"))
+  :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-desktop-default-directory "bookmark+")
+(defcustom bmkp-desktop-default-directory nil
+  "*Default directory used when reading the name of a desktop file.
+If nil then use the current directory (value of `default-directory')."
+  :type 'directory :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-desktop-jump-save-before-flag "bookmark+")
+(defcustom bmkp-desktop-jump-save-before-flag nil
+  "*Non-nil means `bmkp-desktop-jump' saves the desktop file before switching."
+  :type 'boolean :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-desktop-no-save-vars "bookmark+")
+(defcustom bmkp-desktop-no-save-vars '(search-ring regexp-search-ring kill-ring)
+  "*List of variables not to save when creating a desktop bookmark.
+They are removed from `desktop-globals-to-save' for the duration of
+the save (only)."
+  :type '(repeat (variable :tag "Variable")) :group 'bookmark-plus)
+
+
+;; EWW support
+(when (> emacs-major-version 24)        ; Emacs 25+
+
+  (defcustom bmkp-eww-auto-type 'update-only
+    "How `bmkp-eww-auto-bookmark-mode' behaves when enabled.
+You can toggle this option using `\\[bmkp-toggle-eww-auto-type]'."
+    :type '(choice
+            (const :tag "Create EWW bookmark or update existing EWW bookmark" create-or-update)
+            (const :tag "Update existing EWW bookmark (only)" update-only))
+    :group 'bookmark-plus)
+
+  ;; We do not use `define-obsolete-variable-alias' so that byte-compilation in older Emacs
+  ;; works for newer Emacs too.
+  (defvaralias 'bmkp-eww-buffer-handling 'bmkp-eww-buffer-renaming)
+  (bmkp-make-obsolete-variable 'bmkp-eww-buffer-handling 'bmkp-eww-buffer-renaming "2018-02-23")
+
+  (defcustom bmkp-eww-buffer-renaming nil
+    "Whether and how an EWW buffer is renamed.
+Non-nil values affect EWW behavior even when bookmarks are not used.
+
+* nil:    Do not rename buffer - use `*eww*' (vanilla EWW behavior).
+* `url':  Rename buffer to web-page title plus last 20 chars of URL.
+* `page': Rename buffer to web-page title (only)."
+    :type '(choice
+            (const :tag "Do not rename buffer (use name `*eww*')"                    nil)
+            (const :tag "Rename buffer to web-page title plus last 20 chars of URL"  url)
+            ;; Any symbol other than `page' and nil is treated the same as `page'.
+            (const :tag "Rename buffer to web-page title"                            page))
+    :group 'bookmark-plus)
+
+  (defcustom bmkp-eww-generate-buffer-flag nil
+    "Whether to generate a new buffer when jumping to an EWW bookmark.
+* nil means reuse an existing buffer for the bookmarked URL.
+* Non-nil means use a new buffer."
+    :type 'boolean :group 'bookmark-plus)
+
+  ;; We do not use `define-obsolete-variable-alias' so that byte-compilation in older Emacs
+  ;; works for newer Emacs too.
+  (defvaralias 'bmkp-replace-eww-keys-flag 'bmkp-eww-replace-keys-flag)
+  (bmkp-make-obsolete-variable 'bmkp-replace-eww-keys-flag 'bmkp-eww-replace-keys-flag "2017-01-10")
+
+  (defcustom bmkp-eww-replace-keys-flag t
+    "Non-nil means replace EWW bookmarking keys and menus with Bookmark+ ones.
+If you change the value of this option then you must restart Emacs for
+it to take effect."
+    :type 'boolean :group 'bookmark-plus)
+  )
+
+;;;###autoload (autoload 'bmkp-annotation-modes-inherit-from "bookmark+")
+(defcustom bmkp-annotation-modes-inherit-from (if (fboundp 'org-mode) 'org-mode 'text-mode)
+  "Symbol for mode that bookmark annotation modes are to inherit from.
+Or nil if no parent mode.  The annotation modes are
+`bmkp-edit-annotation-mode' and `bmkp-show-annotation-mode'.
+
+You must restart Emacs after changing the value of this option, for
+the change to take effect."
+  :type  'symbol :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-handle-region-function "bookmark+")
+(defcustom bmkp-handle-region-function 'bmkp-handle-region-default
+  "*Function to handle a bookmarked region."
+  :type 'function :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-info-sort-ignores-directories-flag "bookmark+")
+(defcustom bmkp-info-sort-ignores-directories-flag t
+  "*Non-nil means Info-bookmark sorting uses manual names, not file locations.
+If nil, the absolute file names of the manuals are used.  This can be
+useful if you have bookmarks for multiple Emacs releases, and you want
+the bookmarks for a given release to appear together."
+  :type 'boolean :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-incremental-filter-delay "bookmark+")
+(defcustom bmkp-incremental-filter-delay (if (boundp 'bookmark-search-delay)
+                                             bookmark-search-delay
+                                           0.2)
+  "*Seconds to wait before updating display when filtering bookmarks."
+  :type 'number :group 'bookmark-plus)
+
+
+(when (> emacs-major-version 21)        ; Emacs 22+ (need also `Info-selection-hook').
+
+  (defcustom bmkp-info-auto-type 'create-or-update
+    "How `bmkp-info-auto-bookmark-mode' behaves when enabled.
+You can toggle this option using `\\[bmkp-toggle-info-auto-type]'."
+    :type '(choice
+            (const :tag "Create Info bookmark or update existing Info bookmark" create-or-update)
+            (const :tag "Update existing Info bookmark (only)" update-only))
+    :group 'bookmark-plus)
+
+  )
+
+;; Removed autoload cookie, to avoid (void-variable bookmark-default-file) ;;;###autoload
+(defcustom bmkp-last-as-first-bookmark-file bookmark-default-file
+  "*Whether to use the last-used bookmark file as the first used.
+If nil then Emacs always uses the value of `bookmark-default-file' as
+the initial bookmark file, in any given session.
+
+If non-nil, Emacs uses the last bookmark file you used, in the last
+Emacs session.  If none was recorded then it uses
+`bookmark-default-file'.  The particular non-nil value must be an
+absolute file name \(possibly containing `~') - it is not expanded).
+
+NOTE: A non-nil option value is overwritten by Bookmark+, so that it
+becomes the last-used bookmark file.  A nil value is never
+overwritten."
+  :type '(choice
+          (const :tag "Use `bookmark-default-file' as initial bookmark file" nil)
+          (file  :tag "Use last-used bookmark file as initial bookmark file"
+           :value "~/.emacs.bmk"))
+  :group 'bookmark)
+
+;;;###autoload (autoload 'bmkp-menu-popup-max-length "bookmark+")
+(defcustom bmkp-menu-popup-max-length 20
+  "*Max number of bookmarks for `bookmark-completing-read' to use a menu.
+When choosing a bookmark from a list of bookmarks using
+`bookmark-completing-read', this controls whether to use a menu or
+minibuffer input with completion.
+If t, then always use a menu.
+If nil, then never use a menu.
+If an integer, then use a menu only if there are fewer bookmark
+ choices than the value."
+  :type '(choice
+          (integer :tag "Use a menu if there are fewer bookmark choices than this" 20)
+          (const   :tag "Always use a menu to choose a bookmark" t)
+          (const   :tag "Never use a menu to choose a bookmark" nil))
+  :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-new-bookmark-default-names "bookmark+")
+(defcustom bmkp-new-bookmark-default-names
+  (let ((fns  '((lambda () (let ((ff  (function-called-at-point)))
+                             (and ff  (symbolp ff)  (symbol-name ff)))))))
+    (when (fboundp 'region-or-non-nil-symbol-name-nearest-point) ; Defined in `thingatpt+.el'.
+      (setq fns  (cons 'region-or-non-nil-symbol-name-nearest-point fns)))
+    fns)
+  "Functions to produce the default name for a new bookmark.
+\(The default name for an *existing* bookmark is obtained using
+`bmkp-default-bookmark-name'.)
+
+The option value is a list of functions that do not require an
+argument and return a string (or nil).  They are invoked, in order, to
+produce the default names.
+
+The following names are also provided, after the names described
+above: The value of variable `bookmark-current-bookmark' and the
+return value of function `bookmark-buffer-name', in that order.
+
+These latter names are the defaults provided by vanilla Emacs
+`bookmark.el', so if you want the vanilla behavior then set the option
+value to nil.
+
+For non-interactive use of a default bookmark name, and for Emacs
+prior to Emacs 23 even for interactive use, only the first default
+name is used.
+
+Some functions you might want to use in the option value:
+
+ * `region-or-non-nil-symbol-name-nearest-point'
+ * (lambda () (let ((ff  (function-called-at-point)))
+      (and (symbolp ff)  (symbol-name ff))))
+ * (lambda () (let ((vv  (variable-at-point))) ; `variable-at-point'
+      (and (symbolp vv)  (symbol-name vv))))   ;  returns 0 if no var
+ * `word-at-point'
+ * (lambda () (let ((ss  (symbol-at-point)))
+     (and ss  (symbol-name ss))))
+
+The first of these is defined in library `thingatpt+.el'.  It returns
+the text in the region, if it is active and not empty.  Otherwise it
+returns the name of the (non-`nil') symbol nearest point, within
+maximum search distances `tap-near-point-x-distance' (left and right)
+and `tap-near-point-y-distance' (up and down)."
+  :type '(repeat function) :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-other-window-pop-to-flag "bookmark+")
+(defcustom bmkp-other-window-pop-to-flag t
+  "*Non-nil means other-window bookmark jumping uses `pop-to-buffer'.
+Use nil if you want the vanilla Emacs behavior, which uses
+`switch-to-buffer-other-window'.  That creates a new window even if
+there is already another window showing the buffer."
+  :type 'boolean :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-prompt-for-tags-flag "bookmark+")
+(defcustom bmkp-prompt-for-tags-flag nil
+  "*Non-nil means setting bookmarks interactively prompts for tags to add.
+For an existing bookmark, if option `bmkp-properties-to-keep' includes
+`tags' (which it does by default), then the tags you enter are added
+to any that the bookmark already has - none are removed."
+  :type 'boolean :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-properties-to-keep "bookmark+")
+(defcustom bmkp-properties-to-keep '(tags annotation)
+  "*List of properties to keep when you set an existing bookmark.
+When you set a bookmark that already exists, its properties are
+updated (overwritten), with the exception of those listed here."
+  :type '(repeat symbol) :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-region-search-size "bookmark+")
+(defcustom bmkp-region-search-size 40
+  "*Same as `bookmark-search-size', but specialized for bookmark regions."
+  :type 'integer :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-save-new-location-flag "bookmark+")
+(defcustom bmkp-save-new-location-flag t
+  "*Non-nil means save automatically relocated bookmarks.
+If nil, then the new bookmark location is visited, but it is not saved
+as part of the bookmark definition."
+  :type 'boolean :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-sequence-jump-display-function "bookmark+")
+(defcustom bmkp-sequence-jump-display-function 'pop-to-buffer
+  "*Function used to display the bookmarks in a bookmark sequence."
+  :type 'function :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-show-end-of-region-flag "bookmark+")
+(defcustom bmkp-show-end-of-region-flag t
+  "*Show end of region with `exchange-point-and-mark' when activating a region.
+If nil show only beginning of region."
+  :type 'boolean :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-sort-comparer "bookmark+")
+(defcustom bmkp-sort-comparer '((bmkp-info-node-name-cp bmkp-gnus-cp bmkp-url-cp bmkp-local-file-type-cp)
+                                bmkp-alpha-p) ; This corresponds to `s k'.
+  ;; $$$$$$ An alternative default value: `bmkp-alpha-p', which corresponds to `s n'.
+  "*Predicate or predicates for sorting (comparing) bookmarks.
+This defines the default sort for bookmarks in the bookmark list.
+
+Various sorting commands, such as \\<bookmark-bmenu-mode-map>\
+`\\[bmkp-bmenu-sort-by-bookmark-visit-frequency]', change the value of this
+option dynamically (but they do not save the changed value).
+
+The value must be one of the following:
+
+* nil, meaning do not sort
+
+* a predicate that takes two bookmarks as args
+
+* a list of the form ((PRED...) FINAL-PRED), where each PRED and
+  FINAL-PRED are predicates that take two bookmarks as args
+
+If the value is a list of predicates, then each PRED is tried in turn
+until one returns a non-nil value.  In that case, the result is the
+car of that value.  If no non-nil value is returned by any PRED, then
+FINAL-PRED is used and its value is the result.
+
+Each PRED should return `(t)' for true, `(nil)' for false, or nil for
+undecided.  A nil value means that the next PRED decides (or
+FINAL-PRED, if there is no next PRED).
+
+Thus, a PRED is a special kind of predicate that indicates either a
+boolean value (as a singleton list) or \"I cannot decide - let the
+next guy else decide\".  (Essentially, each PRED is a hook function
+that is run using `run-hook-with-args-until-success'.)
+
+Examples:
+
+ nil           - No sorting.
+
+ string-lessp  - Single predicate that returns nil or non-nil.
+
+ ((p1 p2))     - Two predicates `p1' and `p2', which each return
+                 (t) for true, (nil) for false, or nil for undecided.
+
+ ((p1 p2) string-lessp)
+               - Same as previous, except if both `p1' and `p2' return
+                 nil, then the return value of `string-lessp' is used.
+
+Note that these two values are generally equivalent, in terms of their
+effect (*):
+
+ ((p1 p2))
+ ((p1) p2-plain) where p2-plain is (bmkp-make-plain-predicate p2)
+
+Likewise, these three values generally act equivalently (*):
+
+ ((p1))
+ (() p1-plain)
+ p1-plain        where p1-plain is (bmkp-make-plain-predicate p1)
+
+The PRED form lets you easily combine predicates: use `p1' unless it
+cannot decide, in which case try `p2', and so on.  The value ((p2 p1))
+tries the predicates in the opposite order: first `p2', then `p1' if
+`p2' returns nil.
+
+Using a single predicate or FINAL-PRED makes it easy to reuse an
+existing predicate that returns nil or non-nil.
+
+You can also convert a PRED-type predicate (which returns (t), (nil),
+or nil) into an ordinary predicate, by using function
+`bmkp-make-plain-predicate'.  That lets you reuse elsewhere, as
+ordinary predicates, any PRED-type predicates you define.
+
+For example, this defines a plain predicate to compare by URL:
+ (defalias 'bmkp-url-p (bmkp-make-plain-predicate 'bmkp-url-cp))
+
+Note: As a convention, predefined Bookmark+ PRED-type predicate names
+have the suffix `-cp' (for \"component predicate\") instead of `-p'.
+
+--
+* If you use `\\[bmkp-reverse-multi-sort-order]', then there is a difference in \
+behavior between
+
+   (a) using a plain predicate as FINAL-PRED and
+   (b) using the analogous PRED-type predicate (and no FINAL-PRED).
+
+  In the latter case, `\\[bmkp-reverse-multi-sort-order]' affects when the predicate \
+is tried and
+  its return value.  See `bmkp-reverse-multi-sort-order'."
+  :type '(choice
+          (const    :tag "None (do not sort)" nil)
+          (function :tag "Sorting Predicate")
+          (list     :tag "Sorting Multi-Predicate"
+           (repeat (function :tag "Component Predicate"))
+           (choice
+            (const    :tag "None" nil)
+            (function :tag "Final Predicate"))))
+  :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-su-or-sudo-regexp "bookmark+")
+(defcustom bmkp-su-or-sudo-regexp "\\(/su:\\|/sudo:\\)"
+  "*Regexp to recognize `su' or `sudo' Tramp bookmarks."
+  :type 'regexp :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-tags-for-completion "bookmark+")
+(defcustom bmkp-tags-for-completion 'current
+  "*List of strings used as tags for completion (not an alist).
+The tags can be specified here individually or taken from (a) the
+current bookmark list or (b) one or more bookmark files or both.
+
+\(In Emacs 20 and 21, you cannot choose (b) when customizing, but if
+\(b) was chosen using a later Emacs version then the option value can
+still be used in Emacs 20 and 21.)
+
+If a relative file name is specified for a bookmark file then the
+current value of `default-directory' is used to find the file."
+  :type (if (> emacs-major-version 21)
+            '(choice
+              (const :tag "From current bookmarks only" current)
+              (list :tag "From current bookmarks and other sources"
+               (const  :tag "" current)
+               (repeat :inline t :tag "Additional sources or specific tags"
+                (choice
+                 (string :tag "Specific tag")
+                 (cons   :tag "All tags from a bookmark file"
+                  (const :tag "" bmkfile) (file :must-match t)))))
+              (repeat :tag "Choose sources or specific tags"
+               (choice
+                (string :tag "Specific tag")
+                (cons   :tag "All tags from a bookmark file"
+                 (const :tag "" bmkfile) (file :must-match t)))))
+          ;; A bug in Emacs 20-21 means we must sacrifice the user choice of current plus other sources.
+          '(choice
+            (const :tag "From current bookmarks only" current)
+            (repeat :tag "Choose sources or specific tags" ; A 2nd Emacs 20-21 bug ignores `:tag' for menu.
+             (choice
+              (string :tag "Specific tag")
+              (cons   :tag "All tags from a bookmark file"
+               (const :tag "" bmkfile) (file :must-match t))))))
+  :group 'bookmark-plus)
+
+;; Emacs 20 only.
+(unless (fboundp 'define-minor-mode)
+  (defcustom bmkp-temporary-bookmarking-mode nil
+    "*Non-nil means that bookmarks are temporary (not recorded on disk).
+Setting this variable directly does not take effect;
+use either \\[customize] or command `bmkp-temporary-bookmarking-mode'."
+    :set (lambda (symbol value) (bmkp-temporary-bookmarking-mode (if value 1 -1)))
+    :initialize 'custom-initialize-default
+    :type 'boolean :group 'bookmark-plus :require 'bookmark+))
+
+;;;###autoload (autoload 'bmkp-temporary-bookmarking-mode-hook "bookmark+")
+(defcustom bmkp-temporary-bookmarking-mode-hook ()
+  "*Functions run after entering and exiting temporary-bookmarking mode."
+  :type 'hook :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-this-file/buffer-cycle-sort-comparer "bookmark+")
+(defcustom bmkp-this-file/buffer-cycle-sort-comparer '((bmkp-position-cp))
+  "*`bmkp-sort-comparer' value for cycling this-file/buffer bookmarks.
+Use bookmarks for the currently visited file or (non-file) buffer.
+Some values you might want to use: ((bmkp-position-cp)),
+ ((bmkp-bookmark-creation-cp)), ((bmkp-visited-more-cp)).
+See `bmkp-sort-comparer'."
+  :type '(choice
+          (const    :tag "None (do not sort)" nil)
+          (function :tag "Sorting Predicate")
+          (list     :tag "Sorting Multi-Predicate"
+           (repeat (function :tag "Component Predicate"))
+           (choice
+            (const    :tag "None" nil)
+            (function :tag "Final Predicate"))))
+  :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-guess-default-handler-for-file-flag "bookmark+")
+(defcustom bmkp-guess-default-handler-for-file-flag nil
+  "*Non-nil means guess the default handler when creating a file bookmark.
+This is ignored if a handler can be found using option
+`bmkp-default-handlers-for-file-types'.  Otherwise, this is used by
+function `bmkp-default-handler-for-file' to determine the default
+handler for a given file."
+  :type 'boolean :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-read-bookmark-file-hook "bookmark+")
+(defcustom bmkp-read-bookmark-file-hook ()
+  "*List of functions called, in order, after reading a bookmark file.
+Each function should accept the list of bookmarks read from the file
+as first argument and the bookmark file name as second argument."
+  :type 'hook :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-temporary-bookmarking-mode-lighter "bookmark+")
+(defcustom bmkp-temporary-bookmarking-mode-lighter " Temp-Bmk"
+  "*Lighter for `bmkp-temporary-bookmarking-mode'.
+This string shows in the mode line when `bmkp-temporary-bookmarking-mode'
+is enabled.  Set this to nil or \"\" if you do not want any lighter."
+  :type 'string :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-use-region "bookmark+")
+(defcustom bmkp-use-region t
+  "*Non-nil means visiting a bookmark activates its recorded region."
+  :type '(choice
+          (const :tag "Activate bookmark region (except during cycling)"  t)
+          (const :tag "Do not activate bookmark region"                   nil)
+          (const :tag "Activate bookmark region even during cycling"      cycling-too))
+  :group 'bookmark-plus)
+
+;; We do not use `define-obsolete-variable-alias' so that byte-compilation in older Emacs
+;; works for newer Emacs too.
+;;;###autoload (autoload 'bmkp-w3m-allow-multiple-buffers-flag "bookmark+")
+(when (fboundp 'defvaralias)            ; Emacs 22+
+  (defvaralias 'bmkp-w3m-allow-multi-tabs-flag 'bmkp-w3m-allow-multiple-buffers-flag))
+(bmkp-make-obsolete-variable 'bmkp-w3m-allow-multi-tabs-flag 'bmkp-w3m-allow-multiple-buffers-flag
+                             "2017-01-10")
+
+(defcustom bmkp-w3m-allow-multiple-buffers-flag t
+  "*Non-nil means jump to a W3M bookmark in a new buffer."
+  :type 'boolean :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-write-bookmark-file-hook "bookmark+")
+(defcustom bmkp-write-bookmark-file-hook ()
+  "*List of functions called, in order, after writing a bookmark file.
+Each function should accept the bookmark file name as first argument.
+Used after `after-save-hook'."
+  :type 'hook :group 'bookmark-plus)
+
+;; This and the version of function `Info-bookmark-jump' defined here are also defined in `info+.el',
+;; so that their feature is available if you use either `Info+' or `Bookmark+'.
+;;
+;;;###autoload
+(defcustom Info-bookmark-use-only-node-not-file-flag t
+  "Non-nil means an Info bookmark uses only the node name.
+The recorded Info file name is ignored.  This means use only manuals
+corresponding to the current Emacs session, regardless of the Emacs
+version or platform used to record the bookmark.
+
+A nil value means use the manuals whose absolute file names are
+recorded in the bookmarks.  (But if the file doesn't exist or is
+unreadable, then act as if the value is non-nil.)
+
+A non-nil value means you can use the same bookmark with different
+Emacs installations, including on different platforms.  A nil value
+means that you can use a bookmark to consult the Info manual for a
+different Emacs version from that of the current session."
+  :type 'boolean :group 'bookmark-plus)
+ 
+;;(@* "Internal Variables")
+;;; Internal Variables -----------------------------------------------
+
+(defconst bmkp-non-file-filename "   - no file -"
+  "Name to use for `filename' entry, for non-file bookmarks.")
+
+(defvar bmkp-after-set-hook nil "Hook run after `bookmark-set' sets a bookmark.")
+
+(defvar bmkp-automatic-bookmarks ()
+  "Alist of bookmarks that were created automatically during this session.")
+
+
+;; We do not use `define-obsolete-variable-alias' so that byte-compilation in older Emacs
+;; works for newer Emacs too.
+(when (fboundp 'defvaralias)            ; Emacs 22+
+  (defvaralias 'bmkp-automatic-bookmark-mode-timer 'bmkp-auto-idle-bookmark-mode-timer)
+  (bmkp-make-obsolete-variable 'bmkp-auto-idle-bookmark-mode-timer 'bmkp-automatic-bookmark-mode-timer
+                               "2021-08-18"))
+
+(defvar bmkp-automatic-bookmark-mode-timer nil
+  "Timer for `bmkp-automatic-bookmark-mode'.
+This variable is buffer-local, which means that there is a separate
+timer for each buffer where automatic bookmarking is enabled.
+
+NOTE: For Emacs 20, the variable is not buffer-local, by default.  To
+make it so, do this:
+
+  (make-variable-buffer-local 'bmkp-automatic-bookmark-mode-timer)")
+
+(unless (< emacs-major-version 21) (make-variable-buffer-local 'bmkp-automatic-bookmark-mode-timer))
+
+
+(defvar bmkp-autotemp-all-when-set-p nil "Non-nil means make any bookmark temporary whenever it is set.")
+
+;;; $$$$$$ No - don't bother.
+;;; (defconst bmkp-bookmark-modifier-functions  '(bookmark-prop-set bmkp-replace-existing-bookmark
+;;;                                               bookmark-set-name bookmark-store)
+;;;   "List of functions that modify bookmarks.
+;;; Used to mark modified, unsaved bookmarks, in `*Bookmark List*'.
+;;; Should not include any function that calls another in the list.")
+
+
+;; `defvar' Provided for older Emacs versions.
+(defvar bookmark-after-jump-hook nil
+  "Hook run after `bookmark-jump' jumps to a bookmark.
+Useful for example to unhide text in `outline-mode'.")
+
+(defvar bmkp-before-jump-hook nil
+  "Hook run before `bookmark-jump' jumps to a bookmark.")
+
+(defvar bmkp-copied-tags ()
+  "List of tags copied from a bookmark, for pasting to other bookmarks.")
+
+(defvar bmkp-bookmark-set-confirms-overwrite-p nil
+  "Non-nil means `bookmark-set' requires confirmation about overwriting.")
+
+(defvar bmkp-current-bookmark-file bookmark-default-file
+  "Current bookmark file.
+When you start Emacs, this is initialized according to
+`bmkp-last-as-first-bookmark-file'.
+
+When you load bookmarks using `\\[bmkp-switch-bookmark-file-create]', this is set to the file you
+load.  When you save bookmarks using `bookmark-save' with no prefix
+arg, they are saved to this file.
+
+Loading a bookmark file does not change the value of
+`bookmark-default-file', but it might change the value of
+`bmkp-last-as-first-bookmark-file' (which see).  The value of
+`bookmark-default-file' is never changed, except by your
+customizations.")
+
+(defvar bmkp-desktop-current-file nil
+  "Desktop file from last desktop bookmark jumped to.")
+
+(defvar bmkp-edit-bookmark-orig-record nil
+  "Record of bookmark being edited.")
+
+(defvar bmkp-ffap-max-region-size 1024 ; See also Emacs bug #25243.
+  "Max size of active region used to obtain file-name defaults.
+An active region larger than this many characters prevents
+`bmkp-ffap-guesser' from calling `ffap-guesser'.")
+
+(defvar bmkp-file-bookmark-handlers '(bmkp-jump-dired image-bookmark-jump)
+  "List of functions that handle file or directory bookmarks.
+This is used to determine `bmkp-file-bookmark-p'.")
+
+(defvar bmkp-icicles-search-hits-retrieve-more nil
+  "Non-nil means add hits recorded in bookmark to current search hits.
+Otherwise, replace current with bookmark hits.")
+
+(defvar bmkp-last-bmenu-state-file nil "Last value of option `bmkp-bmenu-state-file'.")
+
+(defvar bmkp-last-bookmark-file bookmark-default-file
+  "Last bookmark file used in this session (or default bookmark file).
+This is a backup for `bmkp-current-bookmark-file'.")
+
+(defvar bmkp-current-nav-bookmark nil "Current bookmark for navigation.")
+
+(defvar bmkp-jump-display-function nil "Function used currently to display a bookmark.")
+
+(defvar bmkp-last-specific-buffer ""
+  "Name of buffer used by `bmkp-last-specific-buffer-p'.")
+
+(defvar bmkp-last-specific-file ""
+  "(Absolute) file name used by `bmkp-last-specific-file-p'.")
+
+(defvar bmkp-modified-bookmarks ()
+  "Alist of bookmarks that have been modified and not saved.")
+
+(defvar bmkp-nav-alist () "Current bookmark alist used for navigation.")
+
+(defvar bmkp-return-buffer nil "Name of buffer to return to.")
+
+(defvar bmkp-reverse-sort-p nil "Non-nil means the sort direction is reversed.")
+
+(defvar bmkp-reverse-multi-sort-p nil
+  "Non-nil means the truth values returned by predicates are complemented.
+This changes the order of the sorting groups, but it does not in
+general reverse that order.  The order within each group is unchanged
+\(not reversed).")
+
+(defvar bmkp-use-w32-browser-p nil
+  "Non-nil means use `w32-browser' in the default bookmark handler.
+That is, use the default Windows application for the bookmarked file.
+This has no effect if function `w32-browser' is not defined.")
+
+(defvar bmkp-latest-bookmark-alist () "Copy of `bookmark-alist' as last filtered.")
+
+(defvar bmkp-last-save-flag-value nil "Last value of option `bookmark-save-flag'.")
+
+(defvar bmkp-sorted-alist ()
+  "Copy of current bookmark alist, as sorted for buffer `*Bookmark List*'.
+Has the same structure as `bookmark-alist'.")
+
+(defvar bmkp-tag-history () "History of tags read from the user.")
+
+(defvar bmkp-tags-alist ()
+  "Alist of all bookmark tags, per option `bmkp-tags-for-completion'.
+Each entry is a full tag: a cons whose car is a tag name, a string.
+This is set by function `bmkp-tags-list'.
+Use that function to update the value.")
+
+
+;; REPLACES ORIGINAL DOC STRING in `bookmark.el'.
+;;
+;; Doc string does not say that the file that was loaded is `bookmark-default-file'.
+;;
+(defvar bookmarks-already-loaded nil
+  "Non-nil means some bookmarks have been loaded during this Emacs session.")
+
+
+;; REPLACES ORIGINAL DOC STRING in `bookmark.el'.
+;;
+;; Doc string reflects `Bookmark+' enhancements.
+;;
+(put 'bookmark-alist 'variable-documentation
+     "Current list of bookmarks (bookmark records).
+Bookmark functions update the value automatically.
+You probably do not want to change the value yourself.
+
+The value is an alist with entries of the form
+ (BOOKMARK-NAME . PARAM-ALIST)
+or the deprecated form (BOOKMARK-NAME PARAM-ALIST).
+
+ BOOKMARK-NAME is the name you gave to the bookmark when creating it.
+ PARAM-ALIST is an alist of bookmark data.  The order of the entries
+  in PARAM-ALIST is not important.  The possible entries are described
+  below.
+
+Bookmarks created using vanilla Emacs (`bookmark.el'):
+
+ (filename . FILENAME)
+ (location . LOCATION)
+ (position . POS)
+ (front-context-string . STR-AFTER-POS)
+ (rear-context-string  . STR-BEFORE-POS)
+ (handler . HANDLER)
+ (annotation . ANNOTATION)
+
+ FILENAME names the bookmarked file.
+ LOCATION names the bookmarked file, URL, or other place (Emacs 23+).
+  FILENAME or LOCATION is what is shown in the bookmark list
+  (`C-x r l') when you use `M-t'.
+ POS is the bookmarked buffer position (position in the file).
+ STR-AFTER-POS is buffer text that immediately follows POS.
+ STR-BEFORE-POS is buffer text that immediately precedes POS.
+ ANNOTATION is a string that you can provide to identify the bookmark.
+  See options `bookmark-use-annotations' and
+  `bookmark-automatically-show-annotations'.
+ HANDLER is a function that provides the bookmark-jump behavior
+  for a specific kind of bookmark.  This is the case for Info
+  bookmarks, for instance (starting with Emacs 23).
+
+Bookmarks created using Bookmark+ are the same as for vanilla Emacs,
+except for the following differences.
+
+1. Visit information is recorded, using entries `visits' and `time':
+
+ (visits . NUMBER-OF-VISITS)
+ (time . TIME-LAST-VISITED)
+
+ NUMBER-OF-VISITS is a whole-number counter.
+
+ TIME-LAST-VISITED is an Emacs time representation, such as is
+ returned by function `current-time'.
+
+2. The buffer name is recorded, using entry `buffer-name'.  It need
+not be associated with a file.
+
+3. If no file is associated with the bookmark, then FILENAME is
+   `   - no file -'.
+
+4. Bookmarks can be tagged by users.  The tag information is recorded
+using entry `tags':
+
+ (tags . TAGS-ALIST)
+
+ TAGS-ALIST is an alist with string keys.
+
+5. A bookmark can be simply a wrapper for a file, in which case it has
+entry `file-handler' instead of `handler'.  When you \"jump\" to such
+a bookmark, the `file-handler' function or shell-command is applied to
+the `filename' entry.  Any `handler' entry present is ignored, as are
+entries such as `position'.  It is only the target file that is
+important.
+
+6. Bookmarks can have individual highlighting, provided by users.
+This overrides any default highlighting.
+
+ (lighting . HIGHLIGHTING)
+
+ HIGHLIGHTING is a property list that contain any of these keyword
+ pairs:
+
+   `:style' - Highlighting style.  Cdrs of `bmkp-light-styles-alist'
+              entries are the possible values.
+   `:face'  - Highlighting face, a symbol.
+   `:when'  - A sexp to be evaluated.  Return value of `:no-light'
+              means do not highlight.
+
+7. The following additional entries are used to record region
+information.  When a region is bookmarked, POS represents the region
+start position.
+
+ (end-position . END-POS)
+ (front-context-region-string . STR-BEFORE-END-POS)
+ (rear-context-region-string . STR-AFTER-END-POS))
+
+ END-POS is the region end position.
+ STR-BEFORE-END-POS is buffer text that precedes END-POS.
+ STR-AFTER-END-POS is buffer text that follows END-POS.
+
+The two context region strings are non-nil only when a region is
+bookmarked.
+
+ NOTE: The relative locations of `front-context-region-string' and
+ `rear-context-region-string' are reversed from those of
+ `front-context-string' and `rear-context-string'.  For example,
+ `front-context-string' is the text that *follows* `position', but
+ `front-context-region-string' *precedes* `end-position'.
+
+8. The following additional entries are used for a Dired bookmark.
+
+ (dired-marked . MARKED-FILES)
+ (dired-subdirs . INSERTED-SUBDIRS)
+ (dired-hidden-dirs . HIDDEN-SUBDIRS)
+ (dired-switches . SWITCHES)
+
+ MARKED-FILES is the list of files that were marked `*'.
+ INSERTED-SUBDIRS is the list of subdirectores that were inserted.
+ HIDDEN-SUBDIRS is the list of inserted subdirs that were hidden.
+ SWITCHES is the string of `dired-listing-switches'.
+
+9. The following additional entries are used for a Gnus bookmark.
+
+ (group . GNUS-GROUP-NAME)
+ (article . GNUS-ARTICLE-NUMBER)
+ (message-id . GNUS-MESSAGE-ID)
+
+ GNUS-GROUP-NAME is the name of a Gnus group.
+ GNUS-ARTICLE-NUMBER is the number of a Gnus article.
+ GNUS-MESSAGE-ID is the identifier of a Gnus message.
+
+10. For a URL bookmark, FILENAME or LOCATION is a URL.
+
+11. A sequence bookmark has this additional entry:
+
+ (sequence . COMPONENT-BOOKMARKS)
+
+ COMPONENT-BOOKMARKS is the list of component bookmark names.
+
+12. A function bookmark has this additional entry, which records the
+FUNCTION:
+
+ (function . FUNCTION)
+
+13. A bookmark-list bookmark has this additional entry, which records
+the state of buffer `*Bookmark List*' at the time it is created:
+
+ (bookmark-list . STATE)
+
+ STATE records the sort order, filter function, omit list, and title.")
+ 
+;;(@* "Compatibility Code for Older Emacs Versions")
+;;; Compatibility Code for Older Emacs Versions ----------------------
+
+(when (< emacs-major-version 23)
+
+  ;; These definitions are for Emacs versions prior to Emacs 23.
+  ;; They are the same as the vanilla Emacs 24+ definitions, except as noted.
+  ;; They let older versions of Emacs handle bookmarks created with Emacs 23+.
+  ;; (Emacs < 23 also needs a compatible `bookmark-make-record' version,
+  ;; but I redefine it for all versions, in any case.)
+
+  (defun Info-bookmark-make-record ()
+    "Create a bookmark record for the current Info node (and point).
+Implements `bookmark-make-record-function' for Info nodes."
+    (let* ((file           (and (stringp Info-current-file)  (file-name-nondirectory Info-current-file)))
+           (bookmark-name  (if file
+                               (concat "(" file ") " Info-current-node)
+                             Info-current-node))
+           (defaults       (delq nil (list bookmark-name file Info-current-node))))
+      `(,bookmark-name
+        ,@(bookmark-make-record-default 'NO-FILE)
+        (filename . ,Info-current-file)
+        (info-node . ,Info-current-node)
+        (handler . Info-bookmark-jump)
+        (defaults . ,defaults))))
+
+  (add-hook 'Info-mode-hook (lambda () (set (make-local-variable 'bookmark-make-record-function)
+                                       'Info-bookmark-make-record)))
+
+  (defvar bookmark-make-record-function 'bookmark-make-record-default
+    "Function called with no arguments, to create a bookmark record.
+Modes can set this buffer-locally to enable bookmarking of locations
+that should be treated specially for the mode.  Global commands can
+bind this and then create a bookmark, to get special treatment
+anywhere.
+
+The function value should return a new bookmark record, which should
+be a cons cell of the form (NAME . ALIST) or just ALIST, where ALIST
+is as described in `bookmark-alist'.  If it cannot construct the
+record, then it should raise an error.
+
+NAME is a string that names the new bookmark.  NAME can be nil, in
+which case a default name is used.
+
+ALIST can contain an entry (handler . FUNCTION) which sets the handler
+to FUNCTION, which is then used instead of `bookmark-default-handler'.
+FUNCTION must accept the same arguments as `bookmark-default-handler'.")
+
+  (defun bookmark-prop-get (bookmark prop)
+    "Return entry (property) PROP of BOOKMARK, or nil if no such entry.
+BOOKMARK is a bookmark name or a bookmark record."
+    (cdr (assq prop (bmkp-bookmark-data-from-record bookmark))))
+
+  (defun bookmark-get-handler (bookmark)
+    "Return the `handler' entry for BOOKMARK.
+BOOKMARK is a bookmark name or a bookmark record."
+    (bookmark-prop-get bookmark 'handler))
+
+  (defun bookmark-jump-noselect (bookmark)
+    "Return the location recorded for BOOKMARK.
+BOOKMARK is a bookmark name or a bookmark record.
+The return value has the form (BUFFER . POINT), where BUFFER is a
+buffer and POINT is the location within BUFFER."
+    (save-excursion (bookmark-handle-bookmark bookmark) (cons (current-buffer) (point)))))
+
+(when (< emacs-major-version 22)
+
+  ;; These definitions are for Emacs versions prior to Emacs 22.
+  ;; They are the same as the vanilla Emacs 22+ definitions, except as noted.
+
+;;;   ;; Bookmark+ doesn't use this, but `bookmark.el' still does.  Who has a slow `baud-rate' now?
+;;;   (defun bookmark-maybe-message (fmt &rest args)
+;;;     "Apply `message' to FMT and ARGS, but only if the display is fast enough."
+;;;     (when (>= baud-rate 9600) (apply 'message fmt args)))
+
+  ;; Emacs 22+ just uses `bookmark-jump-other-window' for the menu also.
+  (defun bmkp-menu-jump-other-window (event)
+    "Jump to BOOKMARK (a point in some file) in another window.
+See `bookmark-jump-other-window'."
+    (interactive "e")
+    (bookmark-popup-menu-and-apply-function 'bookmark-jump-other-window
+                                            "Jump to Bookmark (Other Window)" event)))
+ 
+;;(@* "Core Replacements (`bookmark-*' except `bookmark-bmenu-*')")
+;;; Core Replacements (`bookmark-*' except `bookmark-bmenu-*') -------
+
+
+
+;; REPLACES DOCUMENTATION of ORIGINAL in `bookmark.el'.
+;;
+;; Doc now just says that this option is ignored by Bookmark+.
+(put 'bookmark-sort-flag 'variable-documentation
+     "Ignored by Bookmark+, which uses option `bmkp-sort-comparer' instead.")
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; Changed default value to t.
+;; Added `:tag' strings for clarity.
+;; Doc string says that it applies to all Bookmark+ files, and recommends that you back up your files.
+;;
+(defcustom bookmark-version-control t
+  "Whether to make numbered backups of your bookmarking files.
+This includes bookmark files such as `bookmark-default-file' and also
+Bookmark+ files `bmkp-bmenu-commands-file' and
+`bmkp-bmenu-state-file'.
+
+The option can have value `nospecial', `t', `nil', or `never' .  Value
+`nospecial' means to use the `version-control' value.  The others have
+the same meanings as for option `version-control'.
+
+Use value `t' if your bookmarks are important to you.  Consider also
+using numeric backups.  See also nodes `Backup Names' and `Backup
+Deletion' in the Emacs manual."
+  :type '(choice :tag "When to make numbered backups"
+          (const :tag "Use value of option `version-control'" nospecial)
+          (const :tag "Never"                                 never)
+          (const :tag "If existing already"                   nil)
+          (other :tag "Always"                                t))
+  :group 'bookmark :group 'bookmark-plus)
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; Added value `edit'.
+;;
+(defcustom bookmark-automatically-show-annotations t
+  "*Non-nil means show annotations when jumping to a bookmark.
+If the value is `edit' then open the annotation buffer in edit mode.
+ This has the same effect as using command `bookmark-edit-annotation'.
+Any other non-nil value opens it in read-only mode.
+ This has the same effect as using command `bookmark-show-annotation'."
+  :type '(choice
+          (const :tag "Show annotation read-only"               t)
+          (const :tag "Edit annotation"                         edit)
+          (const :tag "Do not show annotation automatically"    nil))
+  :group 'bookmark :group 'bookmark-plus)
+
+
+(when (< emacs-major-version 23)
+
+
+  ;; REPLACES ORIGINAL in `bookmark.el' (Emacs 20-22).
+  ;;
+  ;; Same as Emacs 23+ version of the function.
+  ;; But the behavior is different from vanilla Emacs, because of the different `bookmark-get-bookmark'
+  ;; behavior: Only if BOOKMARK is a name without that property is it looked up in `bookmark-alist'.
+  ;;
+  (defun bookmark-get-bookmark-record (bookmark)
+    "Return the data part of BOOKMARK, that is, all but the name.
+BOOKMARK is a bookmark name or a bookmark record.
+
+If it is a name with text property `bmkp-full-record', or if it is a
+bookmark record, then it is NOT looked up in `bookmark-alist' (it need
+not belong).  Only if it is a name without that property is it looked
+up in `bookmark-alist'."
+    (let ((data  (cdr (bookmark-get-bookmark bookmark))))
+      ;; A bookmark record is either (NAME ALIST) or (NAME . ALIST).
+      (if (and (null (cdr data))  (consp (caar data)))
+          (car data)
+        data)))
+  )
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; If BOOKMARK is a bookmark-name string that has non-nil property `bmkp-full-record' then just return that.
+;; Only if BOOKMARK is a name without that property is it looked up in `bookmark-alist'.
+;;
+(defun bookmark-get-bookmark (bookmark &optional noerror)
+  "Return the full bookmark (record) that corresponds to BOOKMARK.
+This is just `bmkp-get-bookmark' with non-nil NO-NAME-CHECK-P.
+
+If bookmark is a name with text property `bmkp-full-record', or if it
+is a bookmark record, then it is NOT looked up in `bookmark-alist' (it
+need not belong).  Only if it is a name without that property is it
+looked up in `bookmark-alist'.  The vanilla Emacs version of this
+function always looks up a string BOOKMARK in `bookmark-alist'.
+
+If you want to ensure that BOOKMARK is in `bookmark-alist' even when
+BOOKMARK is a string, then use `bmkp-get-bookmark-in-alist', not
+`bookmark-get-bookmark' or `bmkp-get-bookmark'."
+  (bmkp-get-bookmark bookmark noerror 'NO-NAME-CHECK-P))
+
+
+;; This is like vanilla `bookmark-get-bookmark' in `bookmark.el', but it has these differences:
+;;
+;; 1. If BOOKMARK is a bookmark-name string that has non-nil property `bmkp-full-record'
+;;    then return the value of that property - do not look up the string in `bookmark-alist'.
+;; 2. Handle the should-not-happen case of non-string, non-cons.
+;; 3. Added optional arg NO-NAME-CHECK-P.
+;; 4. Unless NO-NAME-CHECK-P, to be valid when a cons, the car must be a string.
+;;
+(defun bmkp-get-bookmark (bookmark &optional noerror no-name-check-p)
+  "Return the full bookmark (record) that corresponds to BOOKMARK.
+BOOKMARK is a bookmark name or a bookmark record.
+
+This function is like vanilla function `bookmark-get-bookmark', except
+for these differences:
+
+1. If BOOKMARK is a bookmark name instead of a full bookmark then
+   return what `bmkp-bookmark-record-from-name' (with no MEMP check)
+   returns.  That is, if the name has non-nil text property
+   `bmkp-full-record' then use that, without looking up the string in
+   `bookmark-alist'.
+
+2. By default, to be considered a valid bookmark record, it must have
+   a name.  That is, as a cons, its car must be a string.
+
+3. Accepts optional arg NO-NAME-CHECK-P.
+
+Non-nil optional arg NOERROR means return nil if BOOKMARK is not a
+valid bookmark.  If NOERROR is nil then raise an error in this case.
+
+Non-nil optional arg NO-NAME-CHECK-P means don't require that the
+bookmark have a name when checking for a valid bookmark.  That is,
+don't require that a cons bookmark have a string car.  Use this arg if
+you generally want the behavior of `bookmark-get-bookmark' but you
+also want the other advantages of `bmkp-get-bookmark'.
+
+You can use this in place of `bookmark-get-bookmark' and remain
+compatible with vanilla Emacs, if you do either of the following:
+
+* Use non-nil NOERROR.
+* Use nil ERROR and non-nil NO-NAME-CHECK-P.
+
+In those cases you still take advantage of a BOOKMARK that has a name
+with a `bmkp-full-record' property, but there's no requirement that
+BOOKMARK have a name.
+
+This function is like `bmkp-get-bookmark-in-alist', except that
+`bmkp-get-bookmark-in-alist' always tests whether BOOKMARK is in
+`bookmark-alist', regardless of whether BOOKMARK is a string (a
+bookmark name) or a full bookmark.  `bmkp-get-bookmark-in-alist' is
+thus a real test for bookmark existence.  Use `bmkp-get-bookmark' only
+when you do NOT want to look up the bookmark in `bookmark-alist'."
+  ;; Non-nil NO-NAME-CHECK-P means this, like `bookmark-get-bookmark', checks only for a cons.
+  ;; With nil NO-NAME-CHECK-P, the check is for a cons with a string car.  We test for the string (the
+  ;; bookmark name) so that we can distinguish, for example, a list of bookmarks from a single bookmark.
+  (cond ((and (consp bookmark)  (or no-name-check-p  (stringp (car bookmark)))) ; No test of alist membership.
+         bookmark)
+        ((stringp bookmark)             ; No MEMP check.
+         (bmkp-bookmark-record-from-name bookmark noerror))
+        (t (and (not noerror)           ; Return nil if NOERROR.
+                (error "Invalid bookmark: `%s'" bookmark)))))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; Use option `bmkp-new-bookmark-default-names' to obtain the default name.
+;;
+(defun bookmark-make-record ()
+  "Return a new bookmark record (NAME . ALIST) for the current location.
+Start with `bookmark-make-record-function'.  If it does not provide a
+bookmark name, then use option `bmkp-new-bookmark-default-names' to
+provide it.  If that does not provide it then use
+`bookmark-current-bookmark' or `bookmark-buffer-name', in that order."
+  (let ((record  (funcall bookmark-make-record-function))
+        defname)
+    (if (stringp (car record))
+        record
+      (when (car record) (push nil record))
+      (setq defname  (catch 'bookmark-make-record
+                       (dolist (fn  bmkp-new-bookmark-default-names)
+                         (when (functionp fn) ; Be sure it is defined and is a function.
+                           (let ((val  (funcall fn)))
+                             (when (and (stringp val)  (not (string= "" val)))
+                               (throw 'bookmark-make-record val)))))
+                       (or bookmark-current-bookmark  (bookmark-buffer-name))))
+      (when (and defname  (not (stringp defname))) (setq defname  (format "%s" defname))) ; Just in case.
+      (when (string= "" defname) (setq defname "<EMPTY NAME>")) ; You never know.
+      (setcar record  defname)
+      record)))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Added optional args NO-REFRESH-P and NO-MSG-P.
+;; 2. Update the bookmark name also, not just the data, for an existing bookmark.
+;; 3. Use `bmkp-get-bookmark-in-alist' to test whether the bookmark already exists.
+;; 4. Put full bookmark record on bookmark name (inside record) as property `bmkp-full-record'.
+;; 5. Use `bmkp-maybe-save-bookmarks'.
+;; 6. Add the bookmark to `bmkp-modified-bookmarks', and to `bmkp-automatic-bookmarks' if appropriate.
+;; 7. Use `bmkp-refresh/rebuild-menu-list', not `bookmark-bmenu-surreptitiously-rebuild-list'.
+;; 8. Return the bookmark.
+;;
+(defun bookmark-store (bookmark-name data no-overwrite &optional no-refresh-p no-msg-p)
+  "Store the bookmark named BOOKMARK-NAME, giving it DATA.
+Return the new bookmark.
+
+DATA is the bookmark record without its name, i.e., what
+`bmkp-bookmark-data-from-record' returns.
+
+If NO-OVERWRITE is non-nil and bookmark BOOKMARK-NAME already exists
+in the current bookmark list (`bookmark-alist') then record the new
+bookmark but do not discard the old one.  The check for existence uses
+`bmkp-get-bookmark-in-alist'.
+
+Non-nil optional arg NO-REFRESH-P means do not refresh/rebuild the
+bookmark-list display.
+
+Non-nil optional arg NO-MSG-P means do not show progress messages.
+
+Note: In spite of the function name, like all functions that define or
+change bookmarks, this function does not necessarily save your
+bookmark file.  Saving the file depends on `bookmark-save-flag'."
+  (bookmark-maybe-load-default-file)
+  (let ((bname  (copy-sequence bookmark-name))
+        bmk)
+    (unless (featurep 'xemacs)
+      ;; XEmacs's `set-text-properties' does not work on free-standing strings, apparently.
+      (set-text-properties 0 (length bname) () bname))
+    (if (or no-overwrite  (not (setq bmk  (bmkp-get-bookmark-in-alist bname 'NOERROR))))
+        (push (setq bmk  (cons bname data)) bookmark-alist) ; Add new bookmark.
+      (bookmark-set-name bmk bname)     ; Overwrite existing bookmark.
+      (setcdr bmk data))
+    ;; Put the full bookmark on its name as property `bmkp-full-record'.
+    ;; Do this regardless of Emacs version and `bmkp-propertize-bookmark-names-flag'.
+    ;; If it needs to be stripped, that will be done when saving.
+    (put-text-property 0 (length bname) 'bmkp-full-record bmk bname)
+    (bmkp-maybe-save-bookmarks)
+    ;; These two are the same as `add-to-list' with `EQ' (not available for Emacs 20-21).
+    (unless (memq bmk bmkp-modified-bookmarks)
+      (setq bmkp-modified-bookmarks  (cons bmk bmkp-modified-bookmarks)))
+    (when (and (boundp 'bmkp-setting-automatic-bmk-p)
+               (not (memq bmk bmkp-automatic-bookmarks)))
+      (setq bmkp-automatic-bookmarks  (cons bmk bmkp-automatic-bookmarks)))
+    (setq bookmark-current-bookmark  bname)
+    (unless no-refresh-p (bmkp-refresh/rebuild-menu-list bmk no-msg-p))
+    bmk))                               ; Return the bookmark.
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; Mention `C-c C-M-c', not `C-c C-c'.
+;;
+;;;###autoload (autoload 'bookmark-default-annotation-text "bookmark+")
+(defun bookmark-default-annotation-text (bookmark-name)
+  "Return default annotation text for BOOKMARK-NAME.
+The default annotation text is simply some text explaining how to use
+annotations."
+  (concat "#  Type the annotation for bookmark `" bookmark-name "' here.\n"
+          "#  All lines that start with a `#' will be deleted.\n"
+          "#  Type `C-c C-M-c' when done.\n#\n"
+          "#  Author: " (user-full-name) " <" (user-login-name) "@"
+          (system-name) ">\n"
+          "#  Date:    " (current-time-string) "\n"))
+
+
+;; REPLACES ORIGINAL in `bookmark.el' (Emacs 24.4+).
+;;
+;; Usable for older Emacs versions also.
+;;
+;;;###autoload (autoload 'bookmark-insert-annotation "bookmark+")
+(defun bookmark-insert-annotation (bookmark)
+  "Insert annotation for BOOKMARK.
+BOOKMARK is a bookmark name or a bookmark record."
+  (setq bookmark  (bmkp-bookmark-name-from-record (bmkp-get-bookmark-in-alist bookmark)))
+  (insert (funcall (if (boundp 'bookmark-edit-annotation-text-func)
+                       bookmark-edit-annotation-text-func
+                     bookmark-read-annotation-text-func)
+                   bookmark))
+  (let ((annotation  (bookmark-get-annotation bookmark)))
+    (when (and annotation  (not (string-equal annotation ""))) (insert annotation))))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Derive from value of option `bmkp-annotation-modes-inherit-from'.
+;; 2. First, remove parent map from `bookmark-edit-annotation-mode-map', so it is derived anew.
+;; 3. Corrected typo in doc string: *send-EDITED-*.
+;; 4. Need to use `eval', to pick up option value and reset parent keymap.
+;; 5. Bind `C-x C-q' to `bmkp-show-this-annotation-read-only'.
+;;
+;;;###autoload (autoload 'bookmark-edit-annotation-mode "bookmark+")
+(eval
+ `(progn
+   ;; Get rid of default parent, so `bmkp-annotation-modes-inherit-from' is used for the map.
+   (when (keymapp bookmark-edit-annotation-mode-map)
+     (set-keymap-parent bookmark-edit-annotation-mode-map nil))
+   (define-derived-mode bookmark-edit-annotation-mode ,bmkp-annotation-modes-inherit-from
+       "Edit Bookmark Annotation"
+     "Mode for editing the annotation of a bookmark.
+When you have finished composing, use `C-c C-M-c'.
+
+\\{bookmark-edit-annotation-mode-map}")
+    (define-key bookmark-edit-annotation-mode-map "\C-x\C-q"    'bmkp-show-this-annotation-read-only)
+    ;; Define this key because Org mode co-opts `C-c C-c' as a prefix key.
+    (define-key bookmark-edit-annotation-mode-map "\C-c\C-\M-c" 'bookmark-send-edited-annotation)))
+
+(define-derived-mode bookmark-show-annotation-mode bookmark-edit-annotation-mode
+    "Show Bookmark Annotation"
+  "Mode for displaying the annotation of a bookmark.
+
+\\{bookmark-show-annotation-mode-map}"
+  (setq buffer-read-only  t)
+  (define-key bookmark-show-annotation-mode-map "\C-x\C-q" 'bmkp-edit-this-annotation))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Record an empty annotation as nil, not "".
+;; 2. BUG fix: Put point back where it was (on the bookmark just annotated).
+;; 3. Refresh menu list, to pick up the `a' marker.
+;; 4. Make sure it's the annotation buffer that gets killed.
+;; 5. Delete window also, if `misc-cmds.el' loaded.
+;;
+;;;###autoload (autoload 'bookmark-send-edited-annotation "bookmark+")
+(defun bookmark-send-edited-annotation () ; Bound to `C-c C-M-c' in `bookmark-edit-annotation-mode'.
+  "Use buffer contents as annotation for a bookmark.
+Lines beginning with `#' are ignored."
+  (interactive)
+  (unless (derived-mode-p 'bookmark-edit-annotation-mode)
+    (error "Not in mode derived from `bookmark-edit-annotation-mode'"))
+  (goto-char (point-min))
+  (while (< (point) (point-max)) (if (= (following-char) ?#) (bookmark-kill-line t) (forward-line 1)))
+  (let ((annotation      (buffer-substring-no-properties (point-min) (point-max)))
+        (bookmark        bookmark-annotation-name)
+        (annotation-buf  (current-buffer)))
+    (when (string= annotation "") (setq annotation  nil))
+    (bookmark-set-annotation bookmark annotation)
+    (setq bookmark-alist-modification-count  (1+ bookmark-alist-modification-count))
+    (bmkp-refresh/rebuild-menu-list bookmark) ; So display `a' and `*' markers (updated).
+    (if (fboundp 'kill-buffer-and-its-windows)
+        (kill-buffer-and-its-windows annotation-buf) ; Defined in `misc-cmds.el'.
+      (kill-buffer annotation-buf))))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Make it a command (added `interactive' spec).  Prefix arg means add or edit (choose any bookmark).
+;; 2. Manage buffer-modified-p.
+;; 3. Emacs 26+: Added ignored &rest arg to accommodate vanilla Emacs fix to bug #20150 (not a bug for us).
+;;
+;;;###autoload (autoload 'bookmark-edit-annotation "bookmark+")
+(defun bookmark-edit-annotation (bookmark &rest _IGNORED) ; Bound to `C-x x a e'
+  "Pop up a buffer for editing bookmark BOOKMARK's annotation.
+Interactively, you are prompted for the bookmark name.  With a prefix
+arg, you can choose any bookmark.  Otherwise, only annotated bookmarks
+are candidates.
+
+Non-interactively, BOOKMARK is a bookmark name or a bookmark record."
+  (interactive
+   (let ((alist  (bmkp-annotated-alist-only)))
+     (list (bookmark-completing-read (format "%s annotation for bookmark"
+                                             (if current-prefix-arg "Add or edit" "Edit"))
+                                     (bmkp-default-bookmark-name alist)
+                                     alist
+                                     nil
+                                     nil
+                                     (not current-prefix-arg)))))
+  (pop-to-buffer (generate-new-buffer-name "*Bookmark Annotation Compose*"))
+  (bookmark-insert-annotation bookmark)
+  (bookmark-edit-annotation-mode)
+  (setq bookmark-annotation-name  bookmark))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; Added optional arg ALIST.
+;;
+(defun bookmark-all-names (&optional alist)
+  "Return a list of all bookmark names.
+The names are those of the bookmarks in ALIST or, if nil,
+`bookmark-alist'."
+  (bookmark-maybe-load-default-file)
+  (mapcar (lambda (bmk) (bmkp-bookmark-name-from-record bmk)) (or alist  bookmark-alist)))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Added optional args ALIST, PRED, and HIST.
+;; 2. Use helper function `bmkp-completing-read-1', which does this:
+;;    (a) binds `icicle-delete-candidate-object' to (essentially) `bookmark-delete'.
+;;    (b) forces you to enter a non-empty name, if DEFAULT is nil or "".
+;;
+(defun bookmark-completing-read (prompt &optional default alist pred hist use-nil-alist-p)
+  "Read a bookmark name, prompting with PROMPT.
+PROMPT is automatically suffixed with \": \", so do not include that.
+
+DEFAULT is a string or a list of strings.  If the user input is empty
+then return the string (or the first string in the list).  If DEFAULT
+is nil (absent) then return \"\" for empty input.
+
+The bookmark alist argument used for completion is optional arg ALIST.
+If USE-NIL-ALIST-P is nil, then ALIST defaults to `bookmark-alist'.
+
+Optional arg PRED is a predicate used for completion.
+
+Optional arg HIST is a history variable for completion.  Default is
+ `bookmark-history'.
+
+Non-nil optional arg USE-NIL-ALIST-P means do not default ALIST to
+`bookmark-alist': if ALIST is nil then there are no bookmark
+candidates.
+
+If you access this function from a menu, then, depending on the value
+of option `bmkp-menu-popup-max-length' and the number of
+bookmarks in ALIST, you choose the bookmark using a menu or using
+completion.
+
+If you use Icicles, then you can use `S-delete' during completion of a
+bookmark name to delete the bookmark named by the current completion
+candidate."
+  (bmkp-completing-read-1 prompt default alist pred hist nil use-nil-alist-p))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Handles also regions and non-file buffers.
+;; 2. Do not use NO-CONTEXT or POSN if < Emacs 24.
+;;
+(defun bookmark-make-record-default (&optional no-file no-context position visits no-region)
+  "Return the record describing the location of a new bookmark.
+Point must be where the bookmark is to be set.
+
+Non-nil NO-FILE means return only the subset of the record that
+ pertains to the location within the buffer (not also the file name).
+
+Non-nil NO-CONTEXT means do not include the front and rear context
+strings in the record enough.
+
+Non-nil POSITION means record it, not point, as the `position' entry.
+
+Non-nil VISITS means record it as the `visits' entry.
+
+Non-nil NO-REGION means do not include the region end, `end-position'."
+  (unless (> emacs-major-version 23) (setq no-context  nil))
+  (let* ((dired-p  (and (boundp 'dired-buffers)  (car (rassq (current-buffer) dired-buffers))))
+         (buf      (buffer-name))
+         (ctime    (current-time))
+
+         ;; Begin `let*' dependencies.
+         (regionp  (and transient-mark-mode  mark-active  (> (region-end) (region-beginning))))
+         (beg      (if regionp (region-beginning) (or position  (point))))
+         (end      (if regionp (region-end) (point)))
+         (fcs      (and (not no-context)  (if regionp
+                                              (bmkp-position-post-context-region beg end)
+                                            (bmkp-position-post-context beg))))
+         (rcs      (and (not no-context)  (if regionp
+                                              (bmkp-position-pre-context-region beg)
+                                            (bmkp-position-pre-context beg))))
+         (fcrs     (and (not no-context)  regionp  (bmkp-end-position-pre-context beg end)))
+         (ecrs     (and (not no-context)  regionp  (bmkp-end-position-post-context end))))
+    `(,@(unless no-file
+                `((filename . ,(cond ((buffer-file-name) (bookmark-buffer-file-name))
+                                     (dired-p            nil)
+                                     (t                  bmkp-non-file-filename)))))
+      (buffer-name . ,buf)
+      ,@(unless no-context `((front-context-string . ,fcs)))
+      ,@(unless no-context `((rear-context-string . ,rcs)))
+      ,@(unless no-context `((front-context-region-string . ,fcrs)))
+      ,@(unless no-context `((rear-context-region-string  . ,ecrs)))
+      (visits       . ,(or visits  0))
+      (time         . ,ctime)
+      (created      . ,ctime)
+      (position     . ,beg)
+      ,@(when (and regionp  (not no-region)) `((end-position . ,end))))))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; Unless non-nil arg DO-NOT-PROPERTIZE-P, put full bookmark record on bookmark name (inside record),
+;; as property `bmkp-full-record'.
+;;
+(defun bookmark-alist-from-buffer (&optional do-not-propertize-p)
+  "Read and return a bookmark list (in any format) from the current buffer.
+Unless optional arg DO-NOT-PROPERTIZE-P is non-nil, put the full
+bookmark record on the bookmark name (in the record), as a text
+property.  Point is irrelevant and unaffected."
+  (let ((bmks  (save-excursion
+                 (goto-char (point-min))
+                 (if (search-forward bookmark-end-of-version-stamp-marker nil t)
+                     (condition-case err
+                         (read (current-buffer))
+                       (error (error "Cannot read definitions in bookmark file:  %s"
+                                     (error-message-string err))))
+                   ;; Else we're dealing with format version 0
+                   (if (search-forward "(" nil t)
+                       (progn (forward-char -1)
+                              (condition-case err
+                                  (read (current-buffer))
+                                (error (error "Cannot read definitions in bookmark file:  %s"
+                                              (error-message-string err)))))
+                     ;; Else no hope of getting information here.
+                     (error "Buffer is not in bookmark-list format"))))))
+    ;; Put full bookmark on bookmark names as property `bmkp-full-record'.
+    ;; Do this regardless of Emacs version and `bmkp-propertize-bookmark-names-flag'.
+    ;; If property needs to be stripped, that will be done when saving.
+    (unless do-not-propertize-p
+      (let (bname)
+        (dolist (bmk  bmks)
+          (setq bname  (bmkp-bookmark-name-from-record bmk))
+          (put-text-property 0 (length bname) 'bmkp-full-record bmk bname))))
+    bmks))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;;  1. Use `bookmark-make-record'.
+;;  2. Use special default prompts for active region, EWW, W3M, and Gnus.
+;;  3. Use function `bmkp-new-bookmark-default-names', in addition to the name that
+;;     `bookmark-make-record' comes up with, as the list of default values.
+;;  4. Use `bmkp-completing-read-lax', choosing from current buffer's bookmarks.
+;;  5. Numeric prefix arg (diff from plain): all bookmarks as completion candidates.
+;;  6. Ask for confirmation if (a) not plain `C-u' and (b) NAME names an existing bookmark.
+;;  7. Do not overwrite properties listed in option `bmkp-properties-to-keep'.
+;;  8. Added optional args INTERACTIVEP and NO-REFRESH-P.
+;;  9. Prompt for tags if `bmkp-prompt-for-tags-flag' is non-nil.
+;; 10. Possibly highlight bookmark and other bookmarks in buffer, per `bmkp-auto-light-when-set'.
+;; 11. Make bookmark temporary, if `bmkp-autotemp-bookmark-predicates' says to.
+;; 12. Run `bmkp-after-set-hook'.
+;;
+;;;###autoload (autoload 'bookmark-set "bookmark+")
+(defun bookmark-set (&optional name parg interactivep no-refresh-p) ; `C-x r M', `C-x x c M'
+  "Set a bookmark named NAME, then run `bmkp-after-set-hook'.
+If the region is active (`transient-mark-mode') and nonempty, then
+record the region limits in the bookmark.
+
+If NAME is nil, then prompt for the bookmark name.  The default names
+for prompting are as follows (in order of priority):
+
+ * If in W3M mode, then the current W3M title.
+
+ * If in a Gnus mode, then the Gnus summary article header.
+
+ * If on a `man' page, then the page name (command and section).
+
+ * If the region is active and nonempty, then the buffer name followed
+   by \": \" and the region prefix (up to
+   `bmkp-bookmark-name-length-max' chars).
+
+ * The names defined by option `bmkp-new-bookmark-default-names'.
+
+ * The value of variable `bookmark-current-bookmark', the name of the
+   last-used bookmark for the current file.
+
+ * The value returned by function `bookmark-buffer-name'.
+
+For Emacs 23+, all of the names described above are available as
+default values, by repeating `M-n'.  For older Emacs versions, the
+first name provided is the only default value.
+
+While entering a bookmark name at the prompt:
+
+ * You can use (lax) completion against bookmarks in the same buffer.
+   If there are no bookmarks in the current buffer, then all bookmarks
+   are completion candidates.  (See also below, about a numeric prefix
+   argument.)
+
+ * You can use `C-M-w' to yank words from the buffer to the
+   minibuffer.  Repeating `C-M-w' yanks successive words (newlines
+   between yanked words are stripped out).
+
+ * You can use `C-M-u' to insert the name of the last bookmark used in
+   the buffer.  This can be useful as an aid to track your progress
+   through a large file.  (If no bookmark has yet been used, then
+   `C-M-u' inserts the name of the visited file.)
+
+A prefix argument changes the behavior as follows:
+
+ * Numeric prefix arg: Use all bookmarks as completion candidates,
+   instead of just the bookmarks for the current buffer.
+
+ * Plain prefix arg (`C-u'): Do not overwrite a bookmark that has the
+   same name as NAME, if such a bookmark already exists.  Instead,
+   push the new bookmark onto the bookmark alist.
+
+   For use by vanilla Emacs, only the most recently set bookmark named
+   NAME is in effect at any given time, but any others named NAME can
+   become available, should you decide to delete the most recent one.
+
+   For Bookmark+, if option `bmkp-propertize-bookmark-names-flag' is
+   non-`nil' then you can use any number of bookmarks that have the
+   same name.  If that option is `nil' then the behavior is the same
+   as for vanilla Emacs.
+
+Bookmark properties listed in option `bmkp-properties-to-keep' are not
+overwritten when you set an existing bookmark.  Their existing values
+are kept.  Other properties may be updated.  Properties such as
+`position' and `visit' are typically updated, for example, to record
+the new position and the number of visits.
+
+Use `\\[bookmark-delete]' to remove bookmarks (you give it a name, and it removes
+only the first instance of a bookmark with that name from the list of
+bookmarks).
+
+From Lisp code:
+
+* Non-nil INTERACTIVEP means the user can be prompted for
+  confirmation, tags, etc., and it is used for the call to
+  `bookmark-store'.
+
+* Non-nil NO-REFRESH-P is also passed to `bookmark-store'.  It means
+  do not refresh/rebuild the bookmark-list display."
+  (interactive (list nil current-prefix-arg t))
+  (unwind-protect
+       (progn
+         (bookmark-maybe-load-default-file)
+         (setq bookmark-current-point   (point)) ; `bookmark-current-point' is a free var here.
+         ;; Do not set these if they are already set in some other buffer (e.g gnus-art).
+         (unless (and bookmark-yank-point  bookmark-current-buffer)
+           (save-excursion (skip-chars-forward " ") (setq bookmark-yank-point  (point)))
+           (setq bookmark-current-buffer  (current-buffer)))
+         (let* ((record   (bookmark-make-record))
+                (defname  (cond ((and (eq major-mode 'eww-mode)
+                                      (fboundp 'bmkp-make-eww-record) ; Emacs 25+
+                                      (bmkp-eww-title)))
+                                ((eq major-mode 'w3m-mode) w3m-current-title)
+                                ((eq major-mode 'gnus-summary-mode) (elt (gnus-summary-article-header) 1))
+                                ((memq major-mode '(Man-mode woman-mode))
+                                 (buffer-substring (point-min) (save-excursion (goto-char (point-min))
+                                                                               (skip-syntax-forward "^ ")
+                                                                               (point))))
+                                (t nil)))
+                (defname  (and defname  (bmkp-replace-regexp-in-string "\n" " " defname)))
+                (bname    (or name  (bmkp-completing-read-lax
+                                     "Set bookmark"
+                                     (bmkp-new-bookmark-default-names defname)
+                                     (and (or (not parg)  (consp parg)) ; No numeric PARG: all bookmarks.
+                                          (bmkp-specific-buffers-alist-only))
+                                     nil 'bookmark-history (or (not parg)  (consp parg))))))
+           ;; BNAME should not be "" now, since `bmkp-new-bookmark-default-names' should provide default(s)
+           ;; and empty input to `bmkp-completing-read-lax' returns the default.  But just in case...
+           (when (and (string= bname "")  defname) (setq bname  defname))
+           (while (string= "" bname)
+             (message "Enter a NON-EMPTY bookmark name") (sit-for 2)
+             (setq bname  (bmkp-completing-read-lax
+                           "Set bookmark"
+                           (bmkp-new-bookmark-default-names defname)
+                           (and (or (not parg)  (consp parg)) ; No numeric PARG: all bookmarks.
+                                (bmkp-specific-buffers-alist-only))
+                           nil 'bookmark-history (or (not parg)  (consp parg)))))
+           (let ((old-bmk  (bmkp-get-bookmark-in-alist bname 'NOERROR))
+                 old-prop)
+             (when (and interactivep  bmkp-bookmark-set-confirms-overwrite-p  (atom parg)  old-bmk
+                        (not (y-or-n-p (format "Overwrite bookmark `%s'? " bname))))
+               (error "OK, canceled"))
+             (when old-bmk              ; Restore props of existing bookmark per `bmkp-properties-to-keep'.
+               (dolist (prop  bmkp-properties-to-keep)
+                 (bookmark-prop-set record prop (bookmark-prop-get old-bmk prop)))))
+           ;; Maybe make bookmark temporary.
+           ;; Pass RECORD, not BNAME, so `bookmark-prop-set' DTRT in `bmkp-make-bookmark-temporary'.
+           (if bmkp-autotemp-all-when-set-p
+               (bmkp-make-bookmark-temporary record)
+             (catch 'bookmark-set
+               (dolist (pred  bmkp-autotemp-bookmark-predicates)
+                 (when (and (functionp pred)  (funcall pred bname))
+                   (bmkp-make-bookmark-temporary record)
+                   (throw 'bookmark-set t)))))
+           (bookmark-store bname (cdr record) (consp parg) no-refresh-p (not interactivep))
+           (when (and interactivep  bmkp-prompt-for-tags-flag)
+             (bmkp-add-tags bname (bmkp-read-tags-completing) 'NO-UPDATE-P)) ; Do not update here.
+           (case (and (boundp 'bmkp-auto-light-when-set)  bmkp-auto-light-when-set)
+             (autonamed-bookmark       (when (bmkp-autonamed-bookmark-p bname)
+                                         (bmkp-light-bookmark bname)))
+             (non-autonamed-bookmark   (unless (bmkp-autonamed-bookmark-p bname)
+                                         (bmkp-light-bookmark bname)))
+             (any-bookmark             (bmkp-light-bookmark bname))
+             (autonamed-in-buffer      (bmkp-light-bookmarks (bmkp-autonamed-this-buffer-alist-only)
+                                                             nil interactivep))
+             (non-autonamed-in-buffer  (bmkp-light-bookmarks
+                                        (bmkp-remove-if #'bmkp-autonamed-this-buffer-bookmark-p
+                                                        (bmkp-this-buffer-alist-only))
+                                        nil interactivep))
+             (all-in-buffer            (bmkp-light-this-buffer nil interactivep)))
+           (run-hooks 'bmkp-after-set-hook)
+           (if bookmark-use-annotations
+               (bookmark-edit-annotation bname)
+             (goto-char bookmark-current-point)))) ; `bookmark-current-point' is a free var here.
+    (setq bookmark-yank-point     nil
+          bookmark-current-buffer nil)))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Put full bookmark record on the name as property `bmkp-full-record'.
+;; 2. Add BOOKMARK to `bmkp-modified-bookmarks'.
+;; 3. The different `bookmark-get-bookmark' behavior from vanilla Emacs means we can get the right bookmark
+;;    if it has a name with property `bmkp-full-record', without looking it up in `bookmark-alist'.
+;;    But we don't require that BOOKMARK have a name, so calls from vanilla or other code aren't bothered.
+;;
+(defun bookmark-set-name (bookmark newname)
+  "Set name of BOOKMARK to NEWNAME.
+BOOKMARK is a bookmark name or a bookmark record.
+Put the full bookmark on its name as property `bmkp-full-record'.
+Add BOOKMARK to `bmkp-modified-bookmarks'.
+
+If BOOKMARK is a name with text property `bmkp-full-record', or if it
+is a bookmark record, then it is NOT looked up in `bookmark-alist' (it
+need not belong).  If it is a name without that property then it is
+looked up in `bookmark-alist'."
+  (setq bookmark  (bookmark-get-bookmark bookmark))
+  (setcar bookmark newname)
+  ;; Put the full bookmark on its name as property `bmkp-full-record'.
+  ;; Do this regardless of Emacs version and `bmkp-propertize-bookmark-names-flag'.
+  ;; If it needs to be stripped, that will be done when saving.
+  (put-text-property 0 (length newname) 'bmkp-full-record bookmark newname)
+  ;; This is the same as `add-to-list' with `EQ' (not available for Emacs 20-21).
+  (unless (memq bookmark bmkp-modified-bookmarks)
+    (setq bmkp-modified-bookmarks  (cons bookmark bmkp-modified-bookmarks))))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; Prevent adding a newline in a bookmark name when yanking.
+;;
+;;;###autoload (autoload 'bookmark-yank-word "bookmark+")
+(defun bookmark-yank-word ()            ; Bound to `C-M-w' in minibuffer when setting bookmark.
+  "Yank the word at point in `bookmark-current-buffer'.
+Repeat to yank consecutive words from the current buffer, appending
+them to the minibuffer.  However, newline characters between yanked
+words are stripped out."
+  (interactive)
+  (let ((string  (with-current-buffer bookmark-current-buffer
+                   (goto-char bookmark-yank-point)
+                   (buffer-substring-no-properties (point)
+                                                   (progn (forward-word 1)
+                                                          (setq bookmark-yank-point  (point)))))))
+    (setq string  (bmkp-replace-regexp-in-string "\n" "" string))
+    (insert string)))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Separate renaming of obsolete default bookmark name (do it even if not loading the default file).
+;; 2. Load `bmkp-last-as-first-bookmark-file' if it is non-nil.
+;;
+(defun bookmark-maybe-load-default-file ()
+  "If bookmarks have not yet been loaded, load them.
+If `bmkp-last-as-first-bookmark-file' is non-nil, load it.
+Otherwise, load `bookmark-default-file'."
+  ;; If there is no file at `bookmark-default-file' but there is a file with the obsolete default
+  ;; name, then rename that file to the value of `bookmark-default-file'.
+  ;; Do this regardless of whether it is `bookmark-default-file' that we load here.
+  (when (and (file-exists-p bookmark-old-default-file)  (not (file-exists-p bookmark-default-file)))
+    (rename-file bookmark-old-default-file bookmark-default-file))
+  (let ((file-to-load  (bmkp-default-bookmark-file)))
+    (and (not bookmarks-already-loaded)
+         (null bookmark-alist)
+         (file-readable-p file-to-load)
+         (bookmark-load file-to-load t 'nosave)
+         (setq bookmarks-already-loaded  t))))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Save DISPLAY-FUNCTION to `bmkp-jump-display-function' before calling `bookmark-handle-bookmark'.
+;; 2. Update the name and position of an autonamed bookmark, in case it moved.
+;; 3. Possibly highlight bookmark and other bookmarks in buffer, per `bmkp-auto-light-when-jump'.
+;; 4. Added `catch', so a handler can throw to skip the rest of the processing if it wants.
+;;
+(defun bookmark--jump-via (bookmark display-function)
+  "Display BOOKMARK using DISPLAY-FUNCTION.
+Then run `bookmark-after-jump-hook' and show annotations for BOOKMARK.
+BOOKMARK is a bookmark name or a bookmark record.
+DISPLAY-FUNCTION is as in `bookmark-jump'."
+  (bmkp-record-visit bookmark 'BATCHP)
+  (setq bmkp-jump-display-function  display-function)
+  (catch 'bookmark--jump-via
+    (bookmark-handle-bookmark bookmark)
+    (unless (and bmkp-use-w32-browser-p  (fboundp 'w32-browser)  (bookmark-get-filename bookmark))
+      (let ((win  (get-buffer-window (current-buffer) 0)))
+        (when win (set-window-point win (point))))
+      ;; If this is an autonamed bookmark, update its name and position, in case it moved.
+      ;; But don't do this if we're using w32, since we might not have moved to the bookmark position.
+      (when (and (bmkp-autonamed-bookmark-for-buffer-p bookmark (buffer-name))
+                 (not bmkp-use-w32-browser-p))
+        (setq bookmark  (bmkp-update-autonamed-bookmark bookmark)))
+      (case (and (boundp 'bmkp-auto-light-when-jump)  bmkp-auto-light-when-jump)
+        (autonamed-bookmark       (when (bmkp-autonamed-bookmark-p bookmark)
+                                    (bmkp-light-bookmark bookmark nil nil nil 'USE-POINT)))
+        (non-autonamed-bookmark   (unless (bmkp-autonamed-bookmark-p bookmark)
+                                    (bmkp-light-bookmark bookmark nil nil nil 'USE-POINT)))
+        (any-bookmark             (bmkp-light-bookmark bookmark nil nil nil 'USE-POINT))
+        (autonamed-in-buffer      (bmkp-light-bookmarks
+                                   (bmkp-remove-if-not #'bmkp-autonamed-bookmark-p
+                                                       (bmkp-this-buffer-alist-only))
+                                   nil 'MSG))
+        (non-autonamed-in-buffer  (bmkp-light-bookmarks (bmkp-remove-if #'bmkp-autonamed-bookmark-p
+                                                                        (bmkp-this-buffer-alist-only))
+                                                        nil 'MSG))
+        (all-in-buffer            (bmkp-light-this-buffer nil 'MSG))))
+    (let ((orig-buff  (current-buffer))) ; Used by `crosshairs-highlight'.
+      (run-hooks 'bookmark-after-jump-hook))
+    (let ((jump-fn  (bmkp-get-tag-value bookmark "bmkp-jump")))
+      (when jump-fn (funcall jump-fn)))
+    (when bookmark-automatically-show-annotations (bookmark-show-annotation bookmark))))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Added optional arg REQUIRE-NAME-P.  Pass it to `bmkp-get-bookmark'.
+;; 2. Use `bmkp-get-bookmark' instead of `bookmark-get-bookmark', so we can get the right bookmark if
+;;    it has a name with property `bmkp-full-record'.  But unless REQUIRE-NAME-P, don't require that BOOKMARK
+;;    have a name, so calls from vanilla or other code won't be bothered.
+;; 3. Add to beginning, not end, of bookmark record.
+;; 4. Do not use `nconc'.
+;; 5. Respect both old and newer bookmark formats.
+;; 6. Add BOOKMARK to `bmkp-modified-bookmarks'.
+;;
+(defun bookmark-prop-set (bookmark prop val &optional require-name-p)
+  "Set the entry (property) PROP of BOOKMARK to VAL.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a bookmark name then it is looked up in `bookmark-alist'.
+If it is a record then it is NOT looked up (need not belong).
+If it is or has a name that has non-nil property `bmkp-full-record',
+then use the bookmark in `bookmark-alist' that is the value of that
+property.  (use `bmkp-get-bookmark', not `bookmark-get-bookmark'.)"
+  (let* ((bmk   (bmkp-get-bookmark bookmark nil (not require-name-p)))
+         (cell  (assq prop (bmkp-bookmark-data-from-record bmk))))
+    (if cell
+        (setcdr cell val)
+      (setcdr bmk (if (consp (car (cadr bmk)))
+                      (list (cons (cons prop val) (cadr bmk))) ; Old format: ("name" ((filename . "f")...))
+                    (cons (cons prop val) (cdr bmk))))) ; New format:        ("name" (filename . "f")...)
+    ;; This is the same as `add-to-list' with `EQ' (not available for Emacs 20-21).
+    (unless (memq bmk bmkp-modified-bookmarks)
+      (setq bmkp-modified-bookmarks  (cons bmk bmkp-modified-bookmarks)))))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Added optional arg FLIP-USE-REGION-P.
+;; 2. Use `bmkp-default-bookmark-name' as default when interactive.
+;; 3. Use `bmkp-jump-1'.
+;; 4. Added note about Icicles `S-delete' to doc string.
+;;
+;;;###autoload (autoload 'bookmark-jump "bookmark+")
+(defun bookmark-jump (bookmark          ; Bound to `C-x j j', `C-x r b', `C-x x g'
+                      &optional display-function flip-use-region-p)
+  "Jump to bookmark BOOKMARK.
+You may have a problem using this function if the value of variable
+`bookmark-alist' is nil.  If that happens, you need to load in some
+bookmarks.  See function `bookmark-load' for more about this.
+
+If the file pointed to by BOOKMARK no longer exists, you are asked if
+you wish to give the bookmark a new location.  If so, `bookmark-jump'
+jumps to the new location and saves it.
+
+If the bookmark defines a region, then the region is activated if
+`bmkp-use-region' is not-nil or it is nil and you use a prefix
+argument.  A prefix arg temporarily flips the value of
+`bmkp-use-region'.
+
+If you use Icicles, then you can use `S-delete' during completion of a
+bookmark name to delete the bookmark named by the current completion
+candidate.
+
+In Lisp code:
+BOOKMARK is a bookmark name or a bookmark record.
+Non-nil DISPLAY-FUNCTION is a function to display the bookmark.  By
+ default, use `pop-to-buffer-same-window'.
+Non-nil FLIP-USE-REGION-P flips the value of `bmkp-use-region'."
+  (interactive (list (bookmark-completing-read "Jump to bookmark" (bmkp-default-bookmark-name))
+                     nil
+                     current-prefix-arg))
+  (bmkp-jump-1 bookmark (or display-function  'bmkp--pop-to-buffer-same-window) flip-use-region-p))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Added optional arg FLIP-USE-REGION-P.
+;; 2. Use `bmkp-default-bookmark-name' as default when interactive.
+;; 3. Use `bmkp-jump-1'.
+;;
+;;;###autoload (autoload 'bookmark-jump-other-window "bookmark+")
+(defun bookmark-jump-other-window (bookmark &optional flip-use-region-p)
+                                        ; Bound to `C-x 4 j j', `C-x x j', `C-x x o', `C-x x q'
+  "Jump to bookmark BOOKMARK in another window.
+See `bookmark-jump', in particular for info about using a prefix arg."
+  (interactive (list (bookmark-completing-read "Jump to bookmark (in another window)"
+                                               (bmkp-default-bookmark-name))
+                     current-prefix-arg))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window flip-use-region-p))
+
+
+;; REPLACES ORIGINAL in `bookmark.el' (Emacs 27+)
+;;
+;; 1. Added optional arg FLIP-USE-REGION-P.
+;; 2. Use `bmkp-default-bookmark-name' as default when interactive.
+;; 3. Use `bmkp-jump-1'.
+;;
+;;;###autoload (autoload 'bookmark-jump-other-frame "bookmark+")
+(defun bookmark-jump-other-frame (bookmark &optional flip-use-region-p) ; Bound to `C-x 5 B'
+  "Jump to bookmark BOOKMARK in another frame.
+See `bookmark-jump', in particular for info about using a prefix arg."
+  (interactive (list (bookmark-completing-read "Jump to bookmark (in another frame)"
+                                               (bmkp-default-bookmark-name))
+                     current-prefix-arg))
+  (let ((pop-up-frames  t)) (bookmark-jump-other-window bookmark flip-use-region-p)))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Invoke MS Windows `Open' action if `bmkp-use-w32-browser-p' and if `w32-browser' is defined.
+;; 2. Favor entry `file-handler' over entry `handler'.  If the former is available, apply it to the file.
+;; 3. If BOOKMARK has its own handler but that is not a defined function, then use the default handler.
+;;    This lets Emacs 22, for instance, handle Emacs 23+ image bookmarks.
+;; 4. Different relocation message for non-file bookmark.
+;;
+(defun bookmark-handle-bookmark (bookmark)
+  "Call BOOKMARK's handler, or `bookmark-default-handler' if it has none.
+Return nil or raise an error.
+
+BOOKMARK is a bookmark name or a bookmark record.
+
+More precisely:
+
+  If `bmkp-use-w32-browser-p' is non-`nil' and `w32-browser' is
+  defined then invoke the MS Windows `Open' action.
+
+  Else, if BOOKMARK has both `file-handler' and `filename' entries
+  then apply the former to the latter.
+
+  Else, if BOOKMARK has a `handler' entry whose value is a defined
+  function then apply it to BOOKMARK.
+
+  Else, apply the default bookmark handler,
+  `bookmark-default-handler', to BOOKMARK.
+
+The default handler changes the current buffer and point.
+
+If the default handler is used and a file error is raised, the error
+is handled as follows:
+ If BOOKMARK has no `filename' entry, do nothing.
+ Else prompt to relocate the file.
+   If relocated, then try again to handle.  Else raise a file error."
+  (cond ((and bmkp-use-w32-browser-p  (fboundp 'w32-browser)  (bookmark-get-filename bookmark))
+         (w32-browser (bookmark-get-filename bookmark))
+         ;; This `throw' is only for the case where this handler is called from `bookmark--jump-via'.
+         ;; It tells `bookmark--jump-via' to skip the rest of what it does after calling the handler.
+         (condition-case nil (throw 'bookmark--jump-via 'BOOKMARK-HANDLE-BOOKMARK) (no-catch nil)))
+        ((functionp (bookmark-prop-get bookmark 'file-handler))
+         (funcall (bookmark-prop-get bookmark 'file-handler) (bookmark-get-filename bookmark)))
+        ((functionp (bookmark-get-handler bookmark))
+         (funcall (bookmark-get-handler bookmark) (bmkp-get-bookmark bookmark)))
+        (t
+         (condition-case err
+             (funcall 'bookmark-default-handler (bmkp-get-bookmark bookmark))
+           (bookmark-error-no-filename  ; `file-error'
+            ;; BOOKMARK can be either a bookmark name or a bookmark record.
+            ;; If a record, do nothing - assume it is a bookmark used internally by some other package.
+            (when (stringp bookmark)
+              (let ((file             (bookmark-get-filename bookmark))
+                    (use-dialog-box   nil)
+                    (use-file-dialog  nil))
+                (when file
+                  ;; Ask user whether to relocate the file.  If no, signal the file error.
+                  (unless (string= file bmkp-non-file-filename) (setq file  (expand-file-name file)))
+                  (ding)
+                  (cond ((y-or-n-p (if (and (string= file bmkp-non-file-filename)
+                                            (bmkp-get-buffer-name bookmark))
+                                       "Bookmark's buffer does not exist.  Re-create it? "
+                                     (concat (file-name-nondirectory file) " nonexistent.  Relocate \""
+                                             bookmark "\"? ")))
+                         (if (string= file bmkp-non-file-filename)
+                             ;; This is probably not the right way to get the correct buffer, but it's
+                             ;; better than nothing, and it gives the user a chance to DTRT.
+                             (pop-to-buffer (bmkp-get-buffer-name bookmark)) ; Create buffer.
+                           (bookmark-relocate bookmark)) ; Relocate to file.
+                         (funcall (or (bookmark-get-handler bookmark)  'bookmark-default-handler)
+                                  (bmkp-get-bookmark bookmark))) ; Try again
+                        (t
+                         (message "Bookmark not relocated: `%s'" bookmark)
+                         (signal (car err) (cdr err)))))))))))
+  (when (stringp bookmark) (setq bookmark-current-bookmark  bookmark))
+  ;; $$$$$$ The vanilla code returns nil, but there is no explanation of why and no code seems
+  ;; to use the return value.  Perhaps we should return the bookmark instead?
+  nil)                                  ; Return nil if no error.
+
+(put 'bookmark-error-no-filename 'error-conditions
+     '(error bookmark-errors bookmark-error-no-filename))
+(put 'bookmark-error-no-filename 'error-message "Bookmark has no associated file (or directory)")
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Use `bmkp-get-bookmark' instead of `bookmark-get-bookmark', so we can get the right bookmark if
+;;    it has a name with property `bmkp-full-record'.
+;; 2. Support regions, buffer names, and entry `file-handler'.
+;; 3. Handle MS Windows `Open' command if `bmkp-use-w32-browser-p' and if `w32-browser' is defined.
+;;
+(defun bookmark-default-handler (bookmark)
+  "Default handler to jump to the location of BOOKMARK.
+Return nil (or raise an error).
+
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'.
+
+If `bmkp-use-w32-browser-p' is non-nil and function `w32-browser' is
+defined, then call `w32-browser'.  That is, use the default MS Windows
+application for the bookmarked file.
+
+If BOOKMARK has entries `file-handler' and `filename', then apply the
+value of the former to the latter.
+
+If BOOKMARK is an old-style Info bookmark, then go to the Info node.
+
+If BOOKMARK records a nonempty region and `bmkp-use-region' is
+ non-nil then activate the region.
+
+Otherwise, call `bmkp-goto-position' to go to the recorded position."
+  (let* ((bmk            (bmkp-get-bookmark bookmark))
+         (file           (bookmark-get-filename bmk))
+         (buf            (bookmark-prop-get bmk 'buffer))
+         (bufname        (bmkp-get-buffer-name bmk))
+         (pos            (bookmark-get-position bmk))
+         (end-pos        (bmkp-get-end-position bmk))
+         (old-info-node  (and (not (bookmark-get-handler bookmark))  (bookmark-prop-get bmk 'info-node))))
+
+    (cond ((and bmkp-use-w32-browser-p  (fboundp 'w32-browser)  file)  (w32-browser file))
+          ((and (bookmark-prop-get bookmark 'file-handler)  file)
+           (funcall (bookmark-prop-get bookmark 'file-handler) file))
+          (old-info-node                ; Emacs 20-21 Info bookmarks - no handler entry.
+           (progn (require 'info)
+                  (Info-find-node file old-info-node)
+                  (when pos (goto-char pos))))
+          ((not (and bmkp-use-region  pos  end-pos  (/= pos end-pos)))
+           ;; Single-position bookmark (no region).  Go to it.
+           (bmkp-goto-position bmk file buf bufname pos
+                               (bookmark-get-front-context-string bmk)
+                               (bookmark-get-rear-context-string bmk)))
+          (t
+           ;; Bookmark with a region.  Go to it and activate the region.
+           (if (and file  (file-readable-p file)  (not (buffer-live-p buf)))
+;;; $$$$$$$    (with-current-buffer (let ((enable-local-variables  ())) (find-file-noselect file))
+               (with-current-buffer (find-file-noselect file) (setq buf  (buffer-name)))
+             ;; No file found.  If no buffer either, then signal that file doesn't exist.
+             (unless (or (and buf  (get-buffer buf))
+                         (and bufname  (get-buffer bufname)  (not (string= buf bufname))))
+               (signal 'bookmark-error-no-filename (list 'stringp file))))
+           (set-buffer (or buf  bufname))
+           (when bmkp-jump-display-function
+             (save-current-buffer (funcall bmkp-jump-display-function (current-buffer)))
+             (raise-frame))
+           (goto-char (if pos (min pos (point-max)) (point-max)))
+           (when (and pos  (> pos (point-max))) (error "Bookmark position is beyond buffer end"))
+           ;; Activate region.  Relocate it if it moved.  Save relocated bookmark if confirm.
+           (funcall bmkp-handle-region-function bmk)))
+    ;; $$$$$$ The vanilla code returns nil, but there is no explanation of why and no code seems
+    ;; to use the return value.  Perhaps we should return the bookmark instead?
+    nil))                               ; Return nil if no file error.
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Added optional arg NO-REFRESH-P.
+;; 2. Added bookmark default for interactive use.
+;; 3. Added note about `S-delete' to doc string.
+;; 4. Changed arg name: BOOKMARK -> BOOKMARK-NAME.
+;; 5. Update Dired location too, for Dired bookmark.
+;; 6. Refresh menu list, to show new location.
+;;
+;;;###autoload (autoload 'bookmark-relocate "bookmark+")
+(defun bookmark-relocate (bookmark-name &optional no-refresh-p) ; Not bound
+  "Relocate the bookmark named BOOKMARK-NAME to another file.
+You are prompted for the new file name.
+Non-nil optional arg NO-REFRESH-P means do not refresh/rebuild the
+bookmark-list display.
+
+Changes the file associated with the bookmark.
+Useful when a file has been renamed after a bookmark was set in it.
+
+If you use Icicles, then you can use `S-delete' during completion of a
+bookmark name to delete the bookmark named by the current completion
+candidate."
+  (interactive (list (bookmark-completing-read "Bookmark to relocate" (bmkp-default-bookmark-name))))
+  (bookmark-maybe-historicize-string bookmark-name)
+  (bookmark-maybe-load-default-file)
+  (let* ((icicle-unpropertize-completion-result-flag  t) ; For `read-file-name'.
+         (bookmark-filename                           (bookmark-get-filename bookmark-name))
+         (new-filename                                (abbreviate-file-name
+                                                       (expand-file-name
+                                                        (read-file-name
+                                                         (format "Relocate %s to: " bookmark-name)
+                                                         (file-name-directory bookmark-filename))))))
+    (bookmark-set-filename bookmark-name new-filename)
+    ;; Change location for Dired too, but not if different from original file name (e.g. a cons).
+    (let ((dired-dir  (bookmark-prop-get bookmark-name 'dired-directory)))
+      (when (and dired-dir  (equal dired-dir bookmark-filename))
+        (bookmark-prop-set bookmark-name 'dired-directory new-filename))))
+  (bmkp-maybe-save-bookmarks)
+  (when (and bookmark-bmenu-toggle-filenames  (get-buffer bmkp-bmenu-buffer)
+             (get-buffer-window (get-buffer bmkp-bmenu-buffer) 0)
+             (not no-refresh-p))
+    (with-current-buffer (get-buffer bmkp-bmenu-buffer) ; Do NOT just use `bmkp-refresh/rebuild-menu-list'.
+      (bmkp-refresh-menu-list bookmark-name)))) ; So display new location and `*' marker.
+
+
+;; REPLACES ORIGINAL in `bookmark.el' (it was removed from `bookmark.el' in Emacs 24.3 - Emacs bug #19838).
+;;
+;; No change from original, except provide a better doc string.
+;;
+;;;###autoload (autoload 'bookmark-insert-current-bookmark "bookmark+")
+(unless (fboundp 'bookmark-insert-current-bookmark)
+  (defun bookmark-insert-current-bookmark () ; Emacs 24.3+
+    "Insert current-bookmark name or buffer file name, if none.
+That is, if `bookmark-current-bookmark' in `bookmark-current-buffer'
+is not nil then insert that."
+    (interactive)
+    (let ((str  (with-current-buffer bookmark-current-buffer
+                  (or bookmark-current-bookmark  (bookmark-buffer-name)))))
+      (insert str))))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Added bookmark default for interactive use.
+;; 2. Do not add any text properties here.  That's done in `bmkp-bmenu-propertize-item'.
+;; 3. Added note about `S-delete' to doc string.
+;; 4. Changed arg name: BOOKMARK -> BOOKMARK-NAME.
+;;
+;;;###autoload (autoload 'bookmark-insert-location "bookmark+")
+(defun bookmark-insert-location (bookmark-name &optional no-history) ; `C-x x I' (original: `C-x x f')
+  "Insert file or buffer name for the bookmark named BOOKMARK-NAME.
+If a file is bookmarked, insert the recorded file name.
+If a non-file buffer is bookmarked, insert the recorded buffer name.
+
+Optional arg NO-HISTORY means do not record BOOKMARK-NAME in
+`bookmark-history'.
+
+If you use Icicles then you can use `S-delete' during completion of a
+bookmark name to delete the bookmark named by the current completion
+candidate."
+  (interactive
+   (let ((bmk  (bookmark-completing-read "Insert bookmark location" (bmkp-default-bookmark-name))))
+     (if (> emacs-major-version 21) (list bmk) bmk)))
+  (unless no-history (bookmark-maybe-historicize-string bookmark-name))
+  (insert (bookmark-location bookmark-name))) ; Return the line inserted.
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. The different `bookmark-get-bookmark' behavior from vanilla Emacs means we can get the right bookmark
+;;    if it has a name with property `bmkp-full-record', without looking it up in `bookmark-alist'.
+;;    But we don't require that BOOKMARK have a name, so calls from vanilla or other code aren't bothered.
+;; 2. Pass full bookmark to the various "get" functions.
+;; 3. Location returned can be a buffer name.
+;;
+(defun bookmark-location (bookmark)
+  "Return a description of the location of BOOKMARK.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a name with text property `bmkp-full-record', or if it is a
+bookmark record, then it is NOT looked up in `bookmark-alist' (it need
+not belong).  If it is a name without that property then it is looked
+up in `bookmark-alist'.
+
+Look first for entry `location', then for entry `buffer-name' or
+`buffer', then for entry `filename'.  Return the first such entry
+found, or \"-- Unknown location --\" if none is found."
+  (bookmark-maybe-load-default-file)
+  (setq bookmark  (bookmark-get-bookmark bookmark))
+  (or (bookmark-prop-get bookmark 'location)
+      (bmkp-get-buffer-name bookmark)   ; Entry `buffer-name'.
+      (bookmark-prop-get bookmark 'buffer) ; Entry `buffer'.
+      (bookmark-get-filename bookmark)
+      "-- Unknown location --"))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Added BATCHP arg.  Return OLD if BATCHP is non-nil and NEW is nil.
+;; 2. Use `bmkp-completing-read-lax', not `read-from-minibuffer', for new name.
+;; 3. Put `bmkp-full-record' property on new name.
+;; 4. Rename also in marked and omitted lists.
+;; 5. Added note about `S-delete' to doc string.
+;; 6. Refresh menu list, to show new name.
+;;
+;;;###autoload (autoload 'bookmark-rename "bookmark+")
+(defun bookmark-rename (old &optional new batchp) ; Not bound in Bookmark+
+  "Change bookmark's name from OLD to NEW.
+Interactively:
+ If called from the keyboard, then prompt for OLD.
+ If called from the menubar, select OLD from a menu.
+If NEW is nil, then prompt for its string value (unless BATCH).
+
+When entering the NEW name you can use completion against existing
+bookmark names.  This completion is lax, so you can easily edit an
+existing name.  See `bookmark-set' for particular keys available
+during this input.
+
+If BATCHP is non-nil, then do not rebuild the bookmark list.  (NEW
+should be non-nil if BATCH is non-nil.)
+
+If you use Icicles then you can use `S-delete' during completion of a
+bookmark name to delete the bookmark named by the current completion
+candidate."
+  (interactive (list (bookmark-completing-read "Old bookmark name" (bmkp-default-bookmark-name))))
+  (bookmark-maybe-historicize-string old)
+  (bookmark-maybe-load-default-file)
+  (setq bookmark-current-point  (point)) ; `bookmark-current-point' is a free var here.
+  (save-excursion (skip-chars-forward " ") (setq bookmark-yank-point  (point)))
+  (setq bookmark-current-buffer  (current-buffer))
+  (let ((newname  (or new  (and (not batchp)  (bmkp-completing-read-lax "New name" old)))))
+;;; $$$$$$  (read-from-minibuffer "New name: " nil
+;;;           (let ((now-map  (copy-keymap minibuffer-local-map)))
+;;;             (define-key now-map  "\C-w" 'bookmark-yank-word)
+;;;             now-map)
+;;;           nil 'bookmark-history))))
+    (when newname
+      (bookmark-set-name old newname)   ; (This also puts `bmkp-full-record' on bookmark name.)
+      (bmkp-rename-for-marked-and-omitted-lists old newname) ; Rename in marked & omitted lists, if present.
+      (setq bookmark-current-bookmark  newname)
+      (unless batchp
+        (if (and (get-buffer bmkp-bmenu-buffer)  (get-buffer-window (get-buffer bmkp-bmenu-buffer) 0))
+            (with-current-buffer (get-buffer bmkp-bmenu-buffer)
+              (bmkp-refresh-menu-list newname)) ; So the new name is displayed.
+          (bookmark-bmenu-surreptitiously-rebuild-list)))
+      (bmkp-maybe-save-bookmarks))
+    (or newname  old)))                 ; NEWNAME is nil only if BATCHP is non-nil and NEW was nil.
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Added bookmark default for interactive use.
+;; 2. Added note about `S-delete' to doc string.
+;; 3. Changed arg name: BOOKMARK -> BOOKMARK-NAME.
+;;
+(or (fboundp 'bmkp-ORIG-bookmark-insert)
+(fset 'bmkp-ORIG-bookmark-insert (symbol-function 'bookmark-insert)))
+
+;;;###autoload (autoload 'bookmark-insert "bookmark+")
+(defun bookmark-insert (bookmark-name)  ; Bound to `C-x x i'
+  "Insert the text of a bookmarked file.
+BOOKMARK-NAME is the name of the bookmark.
+You may have a problem using this function if the value of variable
+`bookmark-alist' is nil.  If that happens, you need to load in some
+bookmarks.  See function `bookmark-load' for more about this.
+
+If you use Icicles, then you can use `S-delete' during completion of a
+bookmark name to delete the bookmark named by the current completion
+candidate."
+  (interactive (list (bookmark-completing-read "Insert bookmark contents" (bmkp-default-bookmark-name))))
+  (bmkp-ORIG-bookmark-insert bookmark-name))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Accept a bookmark or a bookmark name as arg.
+;; 2. Use `bmkp-default-bookmark-name' as default when interactive.
+;; 3. Use `bmkp-get-bookmark' instead of `bookmark-get-bookmark', so we can get the right bookmark if
+;;    it has a name with property `bmkp-full-record'.
+;; 4. Use `bmkp-get-bookmark-in-alist', not `bookmark-get-bookmark', when checking `bookmark-current-bookmark'.
+;; 5. Remove highlighting for the bookmark.
+;; 6. Doc string includes note about `S-delete' for Icicles.
+;; 7. Update `bmkp-latest-bookmark-alist', `bmkp-bmenu-omitted-bookmarks', and `bmkp-automatic-bookmarks'.
+;; 8. Increment `bookmark-alist-modification-count' even when BATCHP is non-nil.
+;;
+;;;###autoload (autoload 'bookmark-delete "bookmark+")
+(defun bookmark-delete (bookmark &optional batchp) ; Bound to `C-x x d'
+  "Delete the BOOKMARK from the bookmark list.
+BOOKMARK is a bookmark name or a bookmark record.
+Interactively, default to the \"current\" bookmark (that is, the one
+most recently used in this file), if it exists.
+
+If BOOKMARK is a name and it has property `bmkp-full-record' then use
+that property along with the name to find the bookmark to delete.  If
+it is or has a name without property `bmkp-full-record' then
+delete (only) the first bookmark in `bookmark-alist' with that name.
+
+Optional arg BATCHP means do not update buffer `*Bookmark List*'.
+
+If you use Icicles, then you can use `S-delete' during completion of a
+bookmark name to delete the bookmark named by the current completion
+candidate.  In this way, you can delete multiple bookmarks."
+  (interactive (list (bookmark-completing-read "Delete bookmark" (bmkp-default-bookmark-name))))
+
+  ;; $$$$$$ Instead of loading unconditionally, maybe we should just try to delete conditionally?
+  ;; IOW, why not (when bookmarks-already-loaded BODY) instead of `bookmark-maybe-load-default-file'?
+  ;; If it gets called on a hook that gets run before ever loading, then should probably do nothing.
+  ;; Leaving it as is for now (2011-04-06).
+  (bookmark-maybe-load-default-file)
+  (let* ((bmk    (bmkp-get-bookmark bookmark 'NOERROR))
+         (bname  (bmkp-bookmark-name-from-record bmk))) ; BOOKMARK might have been a bookmark.
+    (when bname                         ; Do nothing if BOOKMARK does not represent a bookmark.
+      (bookmark-maybe-historicize-string bname)
+      (when (fboundp 'bmkp-unlight-bookmark) (bmkp-unlight-bookmark bmk 'NOERROR))
+      (setq bookmark-alist                (delq bmk bookmark-alist)
+            bmkp-latest-bookmark-alist    (delq bmk bmkp-latest-bookmark-alist)
+            bmkp-automatic-bookmarks      (delq bmk bmkp-automatic-bookmarks)
+            bmkp-bmenu-omitted-bookmarks  (bmkp-delete-bookmark-name-from-list
+                                           bname bmkp-bmenu-omitted-bookmarks))
+      (unless (bmkp-get-bookmark-in-alist bookmark-current-bookmark 'NOERROR)
+        (setq bookmark-current-bookmark  nil)) ; Make this nil if last occurrence of BMK was deleted.
+       ;; Do NOT refresh/rebuild if BATCHP.  Caller must do that if batching deletions.
+      (unless batchp (bmkp-refresh/rebuild-menu-list))
+      (bmkp-maybe-save-bookmarks))))    ; Increments `bookmark-alist-modification-count'.
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Use `bmkp-current-bookmark-file', not `bookmark-default-file'.
+;; 2. Update `bmkp-last-as-first-bookmark-file' if it is non-nil.
+;; 3. Reset `bmkp-modified-bookmarks' to ().
+;; 4. Call `bmkp-refresh/rebuild-menu-list'.
+;;
+;;;###autoload (autoload 'bookmark-save "bookmark+")
+(defun bookmark-save (&optional parg file) ; Bound to `C-x x s'
+  "Save currently defined bookmarks.
+Save by default in the file named by variable
+`bmkp-current-bookmark-file'.  With a prefix arg, you are prompted for
+the file to save to.
+
+If `bmkp-last-as-first-bookmark-file' is non-nil, update its value to
+the file being saved.
+
+To load bookmarks from a specific file, use `\\[bookmark-load]'
+\(`bookmark-load').
+
+If called from Lisp:
+ With nil PARG and nil FILE, use file `bmkp-current-bookmark-file'.
+ With non-nil FILE, use file FILE.
+ With non-nil PARG, prompt the user for the file to use."
+  (interactive "P")
+  (bookmark-maybe-load-default-file)
+  (let ((file-to-save
+         (cond (file)                   ; Use FILE provided.
+               (parg        (bmkp-read-bookmark-file-name
+                             "File to save bookmarks in: " nil
+                             (bmkp-read-bookmark-file-default)))
+               ((not parg)  bmkp-current-bookmark-file))))
+    (when (file-directory-p file-to-save) (error "`%s' is a directory, not a file" file-to-save))
+    (when (and bmkp-last-as-first-bookmark-file
+               bookmark-save-flag)      ; nil if temporary bookmarking mode.
+      (customize-save-variable 'bmkp-last-as-first-bookmark-file file-to-save))
+    (bookmark-write-file file-to-save))
+  ;; Indicate by the count that we have synced the current bookmark file.
+  ;; If an error has already occurred somewhere, the count will not be set, which is what we want.
+  (setq bookmark-alist-modification-count  0
+        bmkp-modified-bookmarks            ())
+  (bmkp-refresh/rebuild-menu-list))     ; $$$$$$ Should this be done only when interactive?
+
+
+;; From `mule-util.el'
+;;
+(eval-when-compile
+ (defmacro with-coding-priority (coding-systems &rest body)
+   "Execute BODY like `progn' with CODING-SYSTEMS at the front of priority list.
+CODING-SYSTEMS is a list of coding systems.  See `set-coding-system-priority'.
+This affects the implicit sorting of lists of coding systems returned by
+operations such as `find-coding-systems-region'."
+   (let ((current (make-symbol "current")))
+     `(let ((,current (coding-system-priority-list)))
+       (apply #'set-coding-system-priority ,coding-systems)
+       (unwind-protect
+            (progn ,@body)
+         (apply #'set-coding-system-priority ,current))))))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Use `write-file', not `write-region', so backup files are made.
+;; 2. Do not save temporary bookmarks (`bmkp-temporary-bookmark-p').
+;; 3. Added optional arguments ADD and ALT-MSG.
+;;    Do not delete region if ADD.  Position point depending on ADD.
+;; 4. Delete contents only if file does not exist (just in case).  Else `bookmark-maybe-upgrade-file-format'.
+;; 5. Insert code piecewise, to improve performance when saving `bookmark-alist'.
+;;    (Do not let `pp' parse all of `bookmark-alist' at once.)
+;; 6. Unless `bmkp-propertize-bookmark-names-flag', remove text properties from bookmark name and file name.
+;;    Remove them also from bookmark names in a sequence bookmark `sequence' entry.
+;; 7. Bind `print-circle' and `print-gensym' around `pp', to record bNAME with `bmkp-full-record' prop, when
+;;    appropriate.
+;; 8. Use `case', not `cond'.
+;; 9. Run `bmkp-write-bookmark-file-hook' functions after writing the bookmark file.
+;;
+(defun bookmark-write-file (file &optional add alt-msg)
+  "Write `bookmark-alist' to FILE.
+Bookmarks that have a non-nil `bmkp-temp' entry are not saved.
+They are removed from the bookmark file, but not from the current
+bookmark list.
+
+Non-nil optional arg ADD means do not replace the bookmarks in FILE.
+If the value is `append' then append `bookmark-list' to them.  Any
+other non-nil value means prepend `bookmark-list' to them.  Prepending
+means that for some operations the copied bookmarks take precedence
+over existing ones with the same name (since an alist is used).
+
+Non-nil ALT-MSG is a message format string to use in place of the
+default, \"Saving bookmarks to file `%s'...\".  The string must
+contain a `%s' construct, so that it can be passed along with FILE to
+`format'.  At the end, \"done\" is appended to the message."
+  (let ((msg                      (or alt-msg  "Saving bookmarks to file `%s'..."))
+        (coding-system-for-write  (if (boundp 'bookmark-file-coding-system) ; Emacs 25.2+.
+                                      (or coding-system-for-write  bookmark-file-coding-system  'utf-8-emacs)
+                                    coding-system-for-write))
+        (print-length             nil)
+        (print-level              nil)
+        (rem-all-p                (or (not (> emacs-major-version 20)) ; Cannot: (not (boundp 'print-circle)).
+                                      (not bmkp-propertize-bookmark-names-flag)))
+        (existing-buf             (get-file-buffer file))
+        (emacs-lisp-mode-hook     nil)  ; Avoid inserting automatic file header if existing empty file, so
+        (lisp-mode-hook           nil)  ; better chance `bookmark-maybe-upgrade-file-format' signals error.
+        bname fname last-fname start end)
+    (when (file-directory-p file) (error "`%s' is a directory, not a file" file))
+    (message msg (abbreviate-file-name file))
+    (with-current-buffer (let ((enable-local-variables  ())) (find-file-noselect file))
+      (goto-char (point-min))
+      (if (file-exists-p file)
+          (bookmark-maybe-upgrade-file-format)
+        (delete-region (point-min) (point-max)) ; In case a find-file hook inserted a header, etc.
+        (unless (boundp 'bookmark-file-coding-system) ; Emacs < 25.2.
+          (bookmark-insert-file-format-version-stamp))
+        (insert "(\n)"))
+      (setq start  (and (file-exists-p file)
+                        (or (save-excursion (goto-char (point-min))
+                                            (search-forward (concat bookmark-end-of-version-stamp-marker "(")
+                                                            nil t))
+                            (error "Invalid bookmark-file")))
+            end    (and start
+                        (or (save-excursion (goto-char start) (and (looking-at ")") start)) ; Bmk list = ().
+                            (save-excursion (goto-char (point-max)) (re-search-backward "^)" nil t))
+                            (error "Invalid bookmark-file"))))
+      (if (not start)                   ; New file, no header yet.
+          (goto-char 2)
+        ;;  Existing file - delete old bookmarks unless ADD.
+        (unless add (delete-region start end))
+        (goto-char (if (eq add 'append) end start)))
+      (dolist (bmk  bookmark-alist)
+        (unless (bmkp-temporary-bookmark-p bmk)
+          (setq bname  (bookmark-name-from-full-record bmk)
+                fname  (bookmark-get-filename bmk))
+          (cond (rem-all-p              ; Remove text properties from bookmark name and file name.
+                 (set-text-properties 0 (length bname) () bname)
+                 (when fname (set-text-properties 0 (length fname) () fname)))
+                (t                      ; Remove property `face' and any Icicles internal properties.
+                 (remove-text-properties 0 (length bname) '(face                     nil
+                                                            display                  nil
+                                                            help-echo                nil
+                                                            rear-nonsticky           nil
+                                                            icicle-fancy-candidates  nil
+                                                            icicle-mode-line-help    nil
+                                                            icicle-special-candidate nil
+                                                            icicle-user-plain-dot    nil
+                                                            icicle-whole-candidate   nil
+                                                            invisible                nil)
+                                         bname)
+                 (when (boundp 'icicle-candidate-properties-alist) ; Multi-completion indexes + text props.
+                   (dolist (entry  icicle-candidate-properties-alist)
+                     (put-text-property 0 (length bname) (car (cadr entry)) nil bname)))))
+          (setcar bmk bname)
+          (when (setq last-fname  (assq 'filename bmk)) (setcdr last-fname fname))
+          (let ((print-circle  bmkp-propertize-bookmark-names-flag)
+                (print-gensym  bmkp-propertize-bookmark-names-flag))
+            (if (not (and rem-all-p  (bmkp-sequence-bookmark-p bmk)))
+                (pp bmk (current-buffer))
+              ;; Remove text properties from bookmark names in the `sequence' entry of sequence bookmark.
+              (insert "(\"" (let ((seqbname  (copy-sequence (bookmark-name-from-full-record bmk))))
+                              (set-text-properties 0 (length seqbname) () seqbname)
+                              seqbname)
+                      "\"\n")
+              (dolist (prop  (cdr bmk))
+                (if (not (eq 'sequence (car prop)))
+                    (insert " " (pp-to-string prop))
+                  (insert " (sequence " (mapconcat (lambda (bname)
+                                                     (let ((name  (copy-sequence bname)))
+                                                       (set-text-properties 0 (length name) () name)
+                                                       (concat "\"" name "\"")))
+                                                   (cdr prop) " ")
+                          ")\n")))
+              (insert " )\n")))))
+      (when (boundp 'bookmark-file-coding-system) ; Emacs 25.2+.  See bug #25365
+        ;; Make sure specified encoding can encode the bookmarks.  If not, suggest utf-8-emacs as default.
+        (with-coding-priority '(utf-8-emacs)
+          (setq coding-system-for-write  (select-safe-coding-system (point-min) (point-max)
+                                                                    (list t coding-system-for-write))))
+        (when start (delete-region 1 (1- start))) ; Delete old header.
+        (goto-char 1)
+        (bookmark-insert-file-format-version-stamp coding-system-for-write))
+      (let ((version-control        (case bookmark-version-control
+                                      ((nil)      nil)
+                                      (never      'never)
+                                      (nospecial  version-control)
+                                      (t          t)))
+            (require-final-newline  t)
+            (errorp                 nil))
+        (condition-case nil
+            (write-file file)
+          (file-error (setq errorp  t)
+                      ;; Do NOT raise error.  (Need to be able to exit.)
+                      (let ((msg  (format "CANNOT WRITE FILE `%s'" file)))
+                        (if (fboundp 'display-warning)
+                            (display-warning 'bookmark-plus msg)
+                          (message msg)
+                          (sit-for 4)))))
+        (when (boundp 'bookmark-file-coding-system) ; Emacs 25.2+
+          (setq bookmark-file-coding-system  coding-system-for-write))
+        (unless existing-buf (kill-buffer (current-buffer)))
+        (run-hook-with-args 'bmkp-write-bookmark-file-hook file)
+        (unless errorp (message (concat msg "done") file))))))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Added optional arg DUPLICATES-OK.
+;;
+;; 2. Unless DUPLICATES-OK is non-nil, if a bookmark in NEW-LIST is `equal' to a bookmark in `bookmark-alist'
+;;    then do not rename it and do not add it - just ignore it.
+;;
+;; 3. Return value includes how many bookmarks were added and renamed.
+;;    If RETURN-BMKS is non-nil then it also includes which bookmarks were added.
+;;
+(defun bookmark-import-new-list (new-list &optional duplicates-ok return-bmks)
+  "Add NEW-LIST of bookmarks to `bookmark-alist'.
+Unless optional arg DUPLICATES-OK is non-nil, ignore bookmarks that
+are `equal' to bookmarks in `bookmark-alist'.  (This means that all of
+their information is `equal', not just their names.  This includes
+their tags and annotations.)
+
+Rename new bookmarks that are not ignored, as needed, using suffix
+\"<N>\" (N=2,3...) when they conflict with existing bookmark names.
+
+Return a list (NB-RENAMED NB-ADDED BMKS-ADDED) of the number renamed,
+the number added, and the full bookmarks that were added.  If
+RETURN-BMKS is nil then BMKS-ADDED is just nil (the bookmarks are not
+returned)."
+  (let ((names       (bookmark-all-names))
+        (nb-added    0)
+        (nb-renamed  0)
+        (bmks-added  ()))
+    (dolist (full-bmk  new-list)
+      (when (or (and (not (member full-bmk bookmark-alist)) ; Check even if DUPLICATES-OK, to update ADDEDP.
+                     (setq nb-added  (1+ nb-added)))
+                duplicates-ok)
+        (when (bookmark-maybe-rename full-bmk names) (setq nb-renamed  (1+ nb-renamed)))
+        (setq bookmark-alist  (nconc bookmark-alist (list full-bmk)))
+        (push (bookmark-name-from-full-record full-bmk) names)
+        (when return-bmks (push full-bmk bmks-added))))
+    (list nb-renamed nb-added bmks-added)))
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; Return non-nil iff bookmark was renamed.
+;;
+(defun bookmark-maybe-rename (full-record names)
+  "Rename bookmark FULL-RECORD if its current name is already used.
+This is a helper for `bookmark-import-new-list'.
+Return non-nil if the bookmark was renamed, nil otherwise."
+  (let ((found-name  (bookmark-name-from-full-record full-record)))
+    (when (member found-name names)
+      (let ((count     2)
+            (new-name  found-name))
+        (while (member new-name names)
+          (setq new-name  (concat found-name (format "<%d>" count))
+                count     (1+ count)))
+        (bookmark-set-name full-record new-name)
+        (not (string= found-name new-name))))))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;;  1. Prefix arg means OVERWRITE.
+;;  2. Return the list of bookmarks read from FILE.
+;;  3. Use `bmkp-read-bookmark-file-name', not `read-file-name', and use different default.
+;;  4. If OVERWRITE is non-nil:
+;;     * Update `bmkp-last-bookmark-file' to `bmkp-current-bookmark-file'.
+;;     * Update `bmkp-current-bookmark-file' to FILE.
+;;     * Reset bmenu stuff: `bmkp-bmenu-marked-bookmarks', `bmkp-modified-bookmarks',
+;;       `bmkp-flagged-bookmarks', `bmkp-bmenu-omitted-bookmarks', `bmkp-bmenu-filter-function'.
+;;     * If `bmkp-last-as-first-bookmark-file', then update it to FILE and save it to disk.
+;;  5. If the bookmark-file buffer already existed, do not kill it after loading.
+;;  6. Set `bookmarks-already-loaded' regardless of FILE (not just `bookmark-default-file').
+;;  7. Update `bmkp-sorted-alist' (it's a cache).
+;;  8. Final msg says whether overwritten.
+;;  9. Run `bmkp-read-bookmark-file-hook' after reading the bookmark file.
+;; 10. Call `bmkp-bmenu-refresh-menu-list' at end, if interactive.
+;;
+;;;###autoload (autoload 'bookmark-load "bookmark+")
+(defun bookmark-load (file &optional overwrite batchp) ; Bound to `C-x x l'
+  "Load bookmarks from FILE (which must be in the standard format).
+Return the list of bookmarks read from FILE.
+Without a prefix argument (argument OVERWRITE is nil), add the newly
+loaded bookmarks to those already current.  They are saved to the
+current bookmark file when bookmarks are saved.
+
+If you do not use a prefix argument, then no existing bookmarks are
+overwritten.  If you load some bookmarks that have the same names as
+bookmarks already defined in your Emacs session, numeric suffixes
+\"<2>\", \"<3>\",... are appended as needed to the names of those new
+bookmarks to distinguish them.
+
+With a prefix argument, switch the bookmark file currently used,
+*replacing* all currently existing bookmarks with the newly loaded
+bookmarks.  In this case, the value of `bmkp-current-bookmark-file'is
+backed up to `bmkp-last-bookmark-file' and then changed to FILE, so
+bookmarks will subsequently be saved to FILE.
+
+If `bmkp-last-as-first-bookmark-file' is non-nil and is not FILE then
+it is changed to FILE and saved persistently, so that the next Emacs
+session will start with it as the bookmark file.  (The value of
+`bookmark-default-file' is unaffected.)
+
+Interactively, if any bookmarks have been modified since last saved
+then you are asked whether you want to first save them before loading
+FILE.  If you hit `C-g' then both saving and loading are canceled.
+
+`bookmark-load' runs `bmkp-read-bookmark-file-hook' after reading the
+bookmark file.
+
+When called from Lisp, non-nil optional arg BATCHP means this is not
+an interactive call.  In this case, do not interact with the user: do
+not ask whether to save the current (unsaved) bookmark list before
+loading; do not display any load progress messages; and do not
+update/refresh buffer `*Bookmark List*'.
+
+If BATCHP is `save' and bookmarks have been modified since the
+bookmark list was last saved, then save the bookmark list before
+loading.
+
+If BATCHP is any other non-nil value besides `save', do not save the
+bookmark list.
+
+Your initial bookmark file, either `bmkp-last-as-first-bookmark-file'
+or `bookmark-default-file', is loaded automatically by Emacs the first
+time you use bookmarks in a session - you do not need to load it
+manually.  Use `bookmark-load' only to load extra bookmarks (with no
+prefix arg) or an alternative set of bookmarks (with a prefix arg).
+
+If you use `bookmark-load' to load a file that does not contain a
+proper bookmark alist, then when bookmarks are saved the current
+bookmark file will likely become corrupted.  You should load only
+bookmark files that were created using the bookmark functions."
+  (interactive
+   (list (let ((default  (if (bmkp-same-file-p bmkp-current-bookmark-file bmkp-last-bookmark-file)
+                             (bmkp-default-bookmark-file)
+                           bmkp-last-bookmark-file)))
+           (bmkp-read-bookmark-file-name
+            (if current-prefix-arg "Switch to bookmark file: " "Add bookmarks from file: ")
+            (or (file-name-directory default)  "~/")
+            default
+            t))
+         current-prefix-arg))
+  ;; Maybe save first.
+  (when (or (eq batchp 'save)
+            (and (not batchp)  (> bookmark-alist-modification-count 0)
+                 (condition-case err
+                     (yes-or-no-p "Save current bookmarks before loading? (`C-g': cancel load) ")
+                   (quit  (error "OK, canceled"))
+                   (error (error (error-message-string err))))))
+    (bookmark-save))
+  ;; Load.
+  (setq file  (abbreviate-file-name (expand-file-name file)))
+  (when (file-directory-p file) (error "`%s' is a directory, not a file" file))
+  (unless (file-readable-p file) (error "Cannot read bookmark file `%s'" file))
+  (unless batchp (message "Loading bookmarks from `%s'..." file))
+  (let ((existing-buf  (get-file-buffer file))
+        blist)
+    (with-current-buffer (let ((enable-local-variables  ())) (find-file-noselect file))
+      (goto-char (point-min))
+      (bookmark-maybe-upgrade-file-format)
+      (setq blist  (bookmark-alist-from-buffer))
+      (unless (listp blist) (error "Invalid bookmark list in `%s'" file))
+      (cond (overwrite
+             (setq bmkp-last-bookmark-file            bmkp-current-bookmark-file
+                   bmkp-current-bookmark-file         file
+                   bookmark-alist                     blist
+                   bookmark-alist-modification-count  0)
+             (setq bmkp-bmenu-marked-bookmarks        () ; Start from scratch.
+                   bmkp-modified-bookmarks            ()
+                   bmkp-flagged-bookmarks             ()
+                   bmkp-bmenu-omitted-bookmarks       (condition-case nil
+                                                          (eval (car (get 'bmkp-bmenu-omitted-bookmarks
+                                                                          'saved-value)))
+                                                        (error nil))
+                   bmkp-bmenu-filter-function         nil)
+             (when (and bmkp-last-as-first-bookmark-file
+                        (not (bmkp-same-file-p bmkp-last-as-first-bookmark-file file)))
+               (customize-save-variable 'bmkp-last-as-first-bookmark-file file)))
+            (t
+             (bookmark-import-new-list blist)
+             (setq bookmark-alist-modification-count  (1+ bookmark-alist-modification-count))))
+      (setq bookmarks-already-loaded  t ; Systematically, whenever any file is loaded.
+            bmkp-sorted-alist         (bmkp-sort-omit bookmark-alist))
+      (when (boundp 'bookmark-file-coding-system) ; Emacs 25.2+
+        (setq bookmark-file-coding-system  buffer-file-coding-system))
+      (run-hook-with-args 'bmkp-read-bookmark-file-hook blist file)
+      (unless (eq existing-buf (current-buffer)) (kill-buffer (current-buffer))))
+    (unless batchp                      ; If appropriate, *CALLER* MUST refresh/rebuild, if BATCHP.
+      (bmkp-refresh/rebuild-menu-list)
+      (message "%s bookmarks in `%s'" (if overwrite "Switched to" "Added") file))
+    blist))                             ; Return the list of bookmarks read from FILE.
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;;  1. Make it a command (added `interactive' spec).
+;;  2. Use `bmkp-get-bookmark' instead of `bookmark-get-bookmark', so we can get the right bookmark if
+;;     it has a name with property `bmkp-full-record'.
+;;  3. Handle external annotations (jump to their destinations).
+;;  4. Added optional arg MSG-P.  Show message if no annotation.
+;;  5. If `bookmark-automatically-show-annotations' is `edit' then this is `bookmark-edit-annotation'.
+;;  6. Name buffer after the bookmark.
+;;  7. Highlight the title, using face `bmkp-heading'.
+;;  8. MSG-P means message if no annotation.
+;;  9. Set `bookmark-annotation-name'.
+;; 10. Manage `buffer-modified-p'.
+;; 11. Use `, not ', in title.  (Both are tolerated.)
+;; 12. Fit frame to buffer if `one-windowp'.
+;; 13. Restore frame selection.
+;;
+;;;###autoload (autoload 'bookmark-show-annotation "bookmark+")
+(defun bookmark-show-annotation (bookmark &optional msg-p) ; Bound to `C-x x a s'
+  "Show the annotation for BOOKMARK, or follow it if external.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a bookmark name then it is looked up in `bookmark-alist'.
+If it is a record then it is NOT looked up (need not belong).
+If it is or has a name that has non-nil property `bmkp-full-record',
+then use the bookmark in `bookmark-alist' that is the value of that
+property.  Raise no error if it has no name.
+
+If the annotation is external then jump to its destination.
+If no annotation and MSG-P is non-nil, show a no-annotation message.
+
+Opens in read-only or edit mode, as chosen by option
+`bookmark-automatically-show-annotations'.  You can toggle between
+read-only and edit mode using `C-x C-q'."
+  (interactive (list (bookmark-completing-read "Show annotation of bookmark"
+                                               (bmkp-default-bookmark-name)
+                                               (bmkp-annotated-alist-only)
+                                               nil
+                                               nil
+                                               'USE-NIL-ALIST-P)))
+  (let* ((bmk       (bmkp-get-bookmark bookmark 'NOERROR))
+         (bname     (bmkp-bookmark-name-from-record bmk))
+         (ann       (and bmk  (bookmark-get-annotation bmk)))
+         (external  (and ann  (bmkp-get-external-annotation ann))))
+    (if external
+        (bmkp-visit-external-annotation external msg-p)
+      (if (not (and ann  (not (string-equal ann ""))))
+          (when msg-p (message "Bookmark has no annotation"))
+        (if (eq 'edit bookmark-automatically-show-annotations)
+            (bookmark-edit-annotation bookmark)
+          (let ((oframe  (selected-frame)))
+            (save-selected-window
+              (pop-to-buffer (get-buffer-create (format "*`%s' Annotation*" bname)))
+              (let ((buffer-read-only  nil) ; Because buffer might already exist, in view mode.
+                    (buf-modified-p    (buffer-modified-p)))
+                (delete-region (point-min) (point-max))
+                (insert (concat "Annotation for bookmark `" bname "':\n\n"))
+                ;; Use `font-lock-ignore' property from library `font-lock+.el', because Org mode
+                ;; uses font-lock, which would otherwise wipe out the highlighting added here.
+                (add-text-properties (line-beginning-position -1) (line-end-position 1)
+                                     '(face              bmkp-heading
+                                       font-lock-ignore  t))
+                (insert ann)
+                (set-buffer-modified-p buf-modified-p))
+              (goto-char (point-min))
+              (bookmark-show-annotation-mode)
+              (when (fboundp 'fit-frame-if-one-window) (fit-frame-if-one-window))
+              (setq bookmark-annotation-name  bmk))
+            (select-frame-set-input-focus oframe)))))))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Make it a command (added `interactive' spec).
+;; 2. Use `bookmark-maybe-load-default-file', to ensure bookmarks are loaded.
+;; 3. Use name `*Bookmark Annotations*', not `*Bookmark Annotation*'.
+;; 4. Don't list bookmarks that have no annotation.
+;; 5. Highlight bookmark names.  Don't indent annotations.  Add a blank line after each annotation.
+;; 6. Use `view-mode'.  `q' uses `quit-window'.
+;; 7. Fit frame to buffer if `one-windowp'.
+;; 8. Restore frame selection.
+;;
+;;;###autoload (autoload 'bookmark-show-all-annotations "bookmark+")
+(defun bookmark-show-all-annotations () ; Bound to `C-x x a S'
+  "Display the annotations for all bookmarks.
+If called from buffer `*Bookmark List*' then the annotations are shown
+in the current sort order."
+  (interactive)
+  (bookmark-maybe-load-default-file)
+  (let ((obuf    (current-buffer))
+        (oframe  (selected-frame)))
+    (save-selected-window
+      (pop-to-buffer (get-buffer-create "*Bookmark Annotations*"))
+      (let ((buffer-read-only  nil))    ; Because buffer might already exist, in view mode.
+        (delete-region (point-min) (point-max))
+        ;; (Could use `bmkp-annotated-alist-only' here instead.)
+        (dolist (full-record  (if (equal (buffer-name obuf) bmkp-bmenu-buffer)
+                                  (bmkp-sort-omit bookmark-alist
+                                                  (and (not (eq bmkp-bmenu-filter-function
+                                                                'bmkp-omitted-alist-only))
+                                                       bmkp-bmenu-omitted-bookmarks))
+                                bookmark-alist))
+          (let ((ann  (bookmark-get-annotation full-record)))
+            (when (and ann  (not (string-equal ann "")))
+              (insert (concat (bmkp-bookmark-name-from-record full-record) ":\n"))
+              (put-text-property (line-beginning-position 0) (line-end-position 0) 'face 'bmkp-heading)
+              (insert ann) (unless (bolp) (insert "\n\n")))))
+        (goto-char (point-min))
+        (if (> emacs-major-version 23)  ; Incompatible change introduced in Emacs 24.1
+            (view-mode-enter)
+          (view-mode-enter (cons (selected-window) (cons nil 'quit-window))))
+        (when (fboundp 'fit-frame-if-one-window) (fit-frame-if-one-window))))
+    (select-frame-set-input-focus oframe)))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; Save menu-list state to `bmkp-bmenu-state-file'.
+;;
+(defun bookmark-exit-hook-internal ()   ; This goes on `kill-emacs-hook'.
+  "Save currently defined bookmarks and perhaps bookmark menu-list state.
+Run `bookmark-exit-hook', then save bookmarks if they were updated.
+Then save menu-list state to file `bmkp-bmenu-state-file', but only if
+that option is non-nil."
+  (run-hooks 'bookmark-exit-hook)
+  (when (bookmark-time-to-save-p t)
+    (condition-case err                 ; Do NOT raise error.  (Need to be able to exit.)
+        (bookmark-save)
+      (error (if (fboundp 'display-warning)
+                 (display-warning 'bookmark-plus (error-message-string err))
+               (message (error-message-string err))
+               (sit-for 4))
+             nil)))
+  (bmkp-save-menu-list-state))
+ 
+;;(@* "Bookmark+ Functions (`bmkp-*')")
+;;; Bookmark+ Functions (`bmkp-*') -----------------------------------
+
+
+;;(@* "Filter Functions")
+;;  *** Filter Functions ***
+
+(put 'bmkp-all-tags-alist-only 'bmkp-read-arg 'bmkp-read-tags-completing)
+(defun bmkp-all-tags-alist-only (tags)
+  "`bookmark-alist', but with only bookmarks having all their tags in TAGS.
+Does not include bookmarks that have no tags.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not
+   (lambda (bmk)
+     (lexical-let* ((tgs       tags)
+                    (bmk-tags  (bmkp-get-tags bmk)))
+       (and bmk-tags  (bmkp-every (lambda (tag) (member (bmkp-tag-name tag) tgs)) bmk-tags))))
+   bookmark-alist))
+
+(put 'bmkp-all-tags-regexp-alist-only 'bmkp-read-arg 'bmkp-read-regexp)
+(defun bmkp-all-tags-regexp-alist-only (regexp)
+  "`bookmark-alist', but with only bookmarks having all tags match REGEXP.
+Does not include bookmarks that have no tags.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not
+   (lexical-let ((rg  regexp))
+     (lambda (bmk)
+       (let ((bmk-tags  (bmkp-get-tags bmk)))
+         (and bmk-tags
+              (bmkp-every (lambda (tag) (bmkp-string-match-p rg (bmkp-tag-name tag))) bmk-tags)))))
+   bookmark-alist))
+
+(defun bmkp-annotated-alist-only ()
+  "`bookmark-alist', but only for bookmarks with non-empty annotations.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-annotated-bookmark-p bookmark-alist))
+
+(defun bmkp-autofile-alist-only (&optional prefix)
+  "`bookmark-alist', filtered to retain only autofile bookmarks.
+With non-nil arg PREFIX, the bookmark names must all have that PREFIX."
+  (bookmark-maybe-load-default-file)
+  (if (not prefix)
+      (bmkp-remove-if-not #'bmkp-autofile-bookmark-p bookmark-alist)
+    (bmkp-remove-if-not (lexical-let ((pref  prefix)) (lambda (bmk) (bmkp-autofile-bookmark-p bmk pref)))
+                        bookmark-alist)))
+
+(put 'bmkp-autofile-all-tags-alist-only 'bmkp-read-arg 'bmkp-read-tags-completing)
+(defun bmkp-autofile-all-tags-alist-only (tags)
+  "`bookmark-alist', with only autofiles having all tags in TAGS.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not
+   (lexical-let ((tgs  tags))
+     (lambda (bmk)
+       (and (bmkp-autofile-bookmark-p bmk)  (bmkp-get-tags bmk)
+            (bmkp-every (lexical-let ((bk  bmk)) (lambda (tag) (bmkp-has-tag-p bk tag))) tgs))))
+   bookmark-alist))
+
+(put 'bmkp-autofile-all-tags-regexp-alist-only 'bmkp-read-arg 'bmkp-read-regexp)
+(defun bmkp-autofile-all-tags-regexp-alist-only (regexp)
+  "`bookmark-alist', with only autofiles having all tags match REGEXP.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not
+   (lexical-let ((rg  regexp))
+     (lambda (bmk)
+       (and (bmkp-autofile-bookmark-p bmk)
+            (let ((bmk-tags  (bmkp-get-tags bmk)))
+              (and bmk-tags
+                   (bmkp-every (lambda (tag) (bmkp-string-match-p rg (bmkp-tag-name tag))) bmk-tags))))))
+   bookmark-alist))
+
+(put 'bmkp-autofile-some-tags-alist-only 'bmkp-read-arg 'bmkp-read-tags-completing)
+(defun bmkp-autofile-some-tags-alist-only (tags)
+  "`bookmark-alist', with only autofiles having some tags in TAGS.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not
+   (lambda (bmk) (and (bmkp-autofile-bookmark-p bmk)
+                      (bmkp-some (lexical-let ((bk  bmk)) (lambda (tag) (bmkp-has-tag-p bk tag)))  tags)))
+   bookmark-alist))
+
+(put 'bmkp-autofile-some-tags-regexp-alist-only 'bmkp-read-arg 'bmkp-read-regexp)
+(defun bmkp-autofile-some-tags-regexp-alist-only (regexp)
+  "`bookmark-alist', with only autofiles having some tags match REGEXP.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not
+   (lexical-let ((rg  regexp))
+     (lambda (bmk) (and (bmkp-autofile-bookmark-p bmk)
+                        (bmkp-some (lambda (tag) (bmkp-string-match-p rg (bmkp-tag-name tag)))
+                                   (bmkp-get-tags bmk)))))
+   bookmark-alist))
+(defun bmkp-autonamed-alist-only ()
+  "`bookmark-alist', with only autonamed bookmarks (from any buffers).
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-autonamed-bookmark-p bookmark-alist))
+
+(defun bmkp-autonamed-this-buffer-alist-only ()
+  "`bookmark-alist', with only autonamed bookmarks for the current buffer.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not (lambda (bmk) (bmkp-autonamed-this-buffer-bookmark-p bmk)) bookmark-alist))
+
+(defun bmkp-bookmark-file-alist-only ()
+  "`bookmark-alist', filtered to retain only bookmark-file bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-bookmark-file-bookmark-p bookmark-alist))
+
+(defun bmkp-bookmark-list-alist-only ()
+  "`bookmark-alist', filtered to retain only bookmark-list bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-bookmark-list-bookmark-p bookmark-alist))
+
+(defun bmkp-buffer-alist-only ()
+  "`bookmark-alist', filtered to retain only non-file buffer bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-buffer-bookmark-p bookmark-alist))
+
+(defun bmkp-desktop-alist-only ()
+  "`bookmark-alist', filtered to retain only desktop bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-desktop-bookmark-p bookmark-alist))
+
+(defun bmkp-dired-alist-only ()
+  "`bookmark-alist', filtered to retain only Dired bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-dired-bookmark-p bookmark-alist))
+
+(defun bmkp-dired-this-dir-alist-only ()
+  "`bookmark-alist', with only Dired bookmarks for the current directory.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-dired-this-dir-bookmark-p bookmark-alist))
+
+(defun bmkp-dired-wildcards-alist-only ()
+  "`bookmark-alist', with only bookmarks for a Dired buffer with wildcards.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-dired-wildcards-bookmark-p bookmark-alist))
+
+(when (fboundp 'bmkp-eww-bookmark-p)    ; Emacs 25+
+
+  (defun bmkp-eww-alist-only ()
+    "`bookmark-alist', filtered to retain only EWW bookmarks.
+A new list is returned (no side effects)."
+    (bookmark-maybe-load-default-file)
+    (bmkp-remove-if-not #'bmkp-eww-bookmark-p bookmark-alist))
+
+  )
+
+(defun bmkp-file-alist-only ()
+  "`bookmark-alist', filtered to retain only file and directory bookmarks.
+This excludes bookmarks that might contain file information but are
+particular in some way - for example, Info bookmarks or Gnus bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-file-bookmark-p bookmark-alist))
+
+(put 'bmkp-file-all-tags-alist-only 'bmkp-read-arg 'bmkp-read-tags-completing)
+(defun bmkp-file-all-tags-alist-only (tags)
+  "`bookmark-alist', with only file bookmarks having all tags in TAGS.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not
+   (lexical-let ((tgs  tags))
+     (lambda (bmk)
+       (and (bmkp-file-bookmark-p bmk)  (bmkp-get-tags bmk)
+            (bmkp-every (lexical-let ((bk  bmk)) (lambda (tag) (bmkp-has-tag-p bk tag)))  tgs))))
+   bookmark-alist))
+
+(put 'bmkp-file-all-tags-regexp-alist-only 'bmkp-read-arg 'bmkp-read-regexp)
+(defun bmkp-file-all-tags-regexp-alist-only (regexp)
+  "`bookmark-alist', with only file bookmarks having all tags match REGEXP.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not
+   (lexical-let ((rg  regexp))
+     (lambda (bmk)
+       (and (bmkp-file-bookmark-p bmk)
+            (let ((bmk-tags  (bmkp-get-tags bmk)))
+              (and bmk-tags
+                   (bmkp-every (lambda (tag) (bmkp-string-match-p rg (bmkp-tag-name tag))) bmk-tags))))))
+   bookmark-alist))
+
+(put 'bmkp-file-some-tags-alist-only 'bmkp-read-arg 'bmkp-read-tags-completing)
+(defun bmkp-file-some-tags-alist-only (tags)
+  "`bookmark-alist', with only file bookmarks having some tags in TAGS.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not
+   (lexical-let ((tgs  tags))
+     (lambda (bmk) (and (bmkp-file-bookmark-p bmk)
+                        (bmkp-some (lexical-let ((bk  bmk)) (lambda (tag) (bmkp-has-tag-p bk tag)))  tgs))))
+   bookmark-alist))
+
+(put 'bmkp-file-some-tags-regexp-alist-only 'bmkp-read-arg 'bmkp-read-regexp)
+(defun bmkp-file-some-tags-regexp-alist-only (regexp)
+  "`bookmark-alist', with only file bookmarks having some tags match REGEXP.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not
+   (lexical-let ((rg  regexp))
+     (lambda (bmk) (and (bmkp-file-bookmark-p bmk)
+                        (bmkp-some (lambda (tag) (bmkp-string-match-p rg (bmkp-tag-name tag)))
+                                   (bmkp-get-tags bmk)))))
+   bookmark-alist))
+
+(defun bmkp-file-this-dir-alist-only ()
+  "`bookmark-alist', filtered with `bmkp-file-this-dir-bookmark-p'.
+Include only files and subdir that are in `default-directory'.
+This excludes bookmarks that might contain file information but are
+particular in some way - for example, Info bookmarks or Gnus bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-file-this-dir-bookmark-p bookmark-alist))
+
+(put 'bmkp-file-this-dir-all-tags-alist-only 'bmkp-read-arg 'bmkp-read-tags-completing)
+(defun bmkp-file-this-dir-all-tags-alist-only (tags)
+  "`bookmark-alist', for files in this dir having all tags in TAGS.
+Include only files and subdir that are in `default-directory'.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not
+   (lexical-let ((tgs  tags))
+     (lambda (bmk)
+       (and (bmkp-file-this-dir-bookmark-p bmk)  (bmkp-get-tags bmk)
+            (bmkp-every (lexical-let ((bk  bmk)) (lambda (tag) (bmkp-has-tag-p bk tag)))  tgs))))
+   bookmark-alist))
+
+(put 'bmkp-file-this-dir-all-tags-regexp-alist-only 'bmkp-read-arg 'bmkp-read-regexp)
+(defun bmkp-file-this-dir-all-tags-regexp-alist-only (regexp)
+  "`bookmark-alist', for files in this dir having all tags match REGEXP.
+Include only files and subdir that are in `default-directory'.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not
+   (lexical-let ((rg  regexp))
+     (lambda (bmk)
+       (and (bmkp-file-this-dir-bookmark-p bmk)
+            (let ((bmk-tags  (bmkp-get-tags bmk)))
+              (and bmk-tags
+                   (bmkp-every (lambda (tag) (bmkp-string-match-p rg (bmkp-tag-name tag)))  bmk-tags))))))
+   bookmark-alist))
+
+(put 'bmkp-file-this-dir-some-tags-alist-only 'bmkp-read-arg 'bmkp-read-tags-completing)
+(defun bmkp-file-this-dir-some-tags-alist-only (tags)
+  "`bookmark-alist', for files in this dir having some tags in TAGS.
+Include only files and subdir that are in `default-directory'.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not
+   (lexical-let ((tgs  tags))
+     (lambda (bmk) (and (bmkp-file-this-dir-bookmark-p bmk)
+                        (bmkp-some (lexical-let ((bk  bmk)) (lambda (tag) (bmkp-has-tag-p bk tag)))  tgs))))
+   bookmark-alist))
+
+(put 'bmkp-file-this-dir-some-tags-regexp-alist-only 'bmkp-read-arg 'bmkp-read-regexp)
+(defun bmkp-file-this-dir-some-tags-regexp-alist-only (regexp)
+  "`bookmark-alist', for files in this dir having some tags match REGEXP.
+Include only files and subdir that are in `default-directory'.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not
+   (lexical-let ((rg  regexp))
+     (lambda (bmk) (and (bmkp-file-this-dir-bookmark-p bmk)
+                        (bmkp-some (lambda (tag) (bmkp-string-match-p rg (bmkp-tag-name tag)))
+                                   (bmkp-get-tags bmk)))))
+   bookmark-alist))
+
+(defun bmkp-function-alist-only ()
+  "`bookmark-alist', filtered to retain only function bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-function-bookmark-p bookmark-alist))
+
+(defun bmkp-gnus-alist-only ()
+  "`bookmark-alist', filtered to retain only Gnus bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-gnus-bookmark-p bookmark-alist))
+
+(defun bmkp-icicles-search-hits-alist-only ()
+  "`bookmark-alist', but only for Icicles search hits bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-icicles-search-hits-bookmark-p bookmark-alist))
+
+(defun bmkp-image-alist-only ()
+  "`bookmark-alist', filtered to retain only image-file bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-image-bookmark-p bookmark-alist))
+
+(defun bmkp-info-alist-only ()
+  "`bookmark-alist', filtered to retain only Info bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-info-bookmark-p bookmark-alist))
+
+(defun bmkp-last-specific-buffer-alist-only ()
+  "`bookmark-alist', but only for `bmkp-last-specific-buffer'.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-last-specific-buffer-p bookmark-alist))
+
+(defun bmkp-last-specific-file-alist-only ()
+  "`bookmark-alist', but only for `bmkp-last-specific-file'.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-last-specific-file-p bookmark-alist))
+
+(defun bmkp-man-alist-only ()
+  "`bookmark-alist', filtered to retain only `man' page bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-man-bookmark-p bookmark-alist))
+
+(defun bmkp-local-file-alist-only ()
+  "`bookmark-alist', filtered to retain only local-file bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-local-file-bookmark-p bookmark-alist))
+
+(defun bmkp-local-non-dir-file-alist-only ()
+  "`bookmark-alist', filtered to retain only local non-dir file bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-local-non-dir-file-bookmark-p bookmark-alist))
+
+(defun bmkp-marked-bookmarks-only ()
+  "Return the list of marked bookmarks."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-marked-bookmark-p bookmark-alist))
+
+(defun bmkp-non-autonamed-alist-only ()
+  "`bookmark-alist', with only non-autonamed bookmarks (from any buffers).
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not (lambda (bmk) (not (bmkp-autonamed-bookmark-p bmk))) bookmark-alist))
+
+(defun bmkp-non-dir-file-alist-only ()
+  "`bookmark-alist', filtered to retain only nondirectory file bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-non-dir-file-bookmark-p bookmark-alist))
+
+(defun bmkp-non-file-alist-only ()
+  "`bookmark-alist', filtered to retain only non-file bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-non-file-bookmark-p bookmark-alist))
+
+(defun bmkp-non-invokable-alist-only ()
+  "`bookmark-alist', filtered to retain only non-invokable bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-non-invokable-bookmark-p bookmark-alist))
+
+(defun bmkp-omitted-alist-only ()
+  "`bookmark-alist', filtered to retain only the omitted bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-omitted-bookmark-p bookmark-alist))
+
+(defun bmkp-omitted-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is an omitted bookmark.
+BOOKMARK is a bookmark name or a bookmark record."
+  (unless (stringp bookmark) (setq bookmark  (bmkp-bookmark-name-from-record bookmark)))
+  (bmkp-bookmark-name-member bookmark bmkp-bmenu-omitted-bookmarks))
+
+(defun bmkp-orphaned-file-alist-only ()
+  "`bookmark-alist', filtered to retain only orphaned file bookmarks."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-orphaned-file-bookmark-p bookmark-alist))
+
+(defun bmkp-orphaned-local-file-alist-only ()
+  "`bookmark-alist', but retaining only orphaned local-file bookmarks."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-orphaned-local-file-bookmark-p bookmark-alist))
+
+(defun bmkp-orphaned-remote-file-alist-only ()
+  "`bookmark-alist', but retaining only orphaned remote-file bookmarks."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-orphaned-remote-file-bookmark-p bookmark-alist))
+
+(defun bmkp-regexp-filtered-annotation-alist-only ()
+  "`bookmark-alist' for annotations matching `bmkp-bmenu-filter-pattern'."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not
+   (lambda (bmk)
+     (let ((annot  (bookmark-get-annotation bmk)))
+       (and (stringp annot)  (not (string= "" annot))
+            (bmkp-string-match-p bmkp-bmenu-filter-pattern annot))))
+   bookmark-alist))                     ; (Could use `bmkp-annotated-alist-only' here instead.)
+
+(defun bmkp-regexp-filtered-bookmark-name-alist-only ()
+  "`bookmark-alist' for bookmarks matching `bmkp-bmenu-filter-pattern'."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not (lambda (bmk)
+                        (bmkp-string-match-p bmkp-bmenu-filter-pattern (bookmark-name-from-full-record bmk)))
+                      bookmark-alist))
+
+(defun bmkp-regexp-filtered-file-name-alist-only ()
+  "`bookmark-alist' for files matching `bmkp-bmenu-filter-pattern'."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not (lambda (bmk) (let ((fname  (bookmark-get-filename bmk)))
+                                      (and fname  (bmkp-string-match-p bmkp-bmenu-filter-pattern fname))))
+                      bookmark-alist))
+
+(defun bmkp-regexp-filtered-tags-alist-only ()
+  "`bookmark-alist' for tags matching `bmkp-bmenu-filter-pattern'."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not (lambda (bmk)
+                        (let ((bmk-tags  (bmkp-get-tags bmk)))
+                          (and bmk-tags  (bmkp-some (lambda (tag)
+                                                      (bmkp-string-match-p bmkp-bmenu-filter-pattern
+                                                                           (bmkp-tag-name tag)))
+                                                    bmk-tags))))
+                      bookmark-alist))
+
+(defun bmkp-region-alist-only ()
+  "`bookmark-alist', filtered to retain only bookmarks that have regions.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-region-bookmark-p bookmark-alist))
+
+(defun bmkp-remote-file-alist-only ()
+  "`bookmark-alist', filtered to retain only remote-file bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-remote-file-bookmark-p bookmark-alist))
+
+(defun bmkp-remote-non-dir-file-alist-only ()
+  "`bookmark-alist', filtered to retain only remote non-dir file bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-remote-non-dir-file-bookmark-p bookmark-alist))
+
+(defun bmkp-sequence-alist-only ()
+  "`bookmark-alist', filtered to retain only sequence bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-sequence-bookmark-p bookmark-alist))  
+
+(defun bmkp-snippet-alist-only ()
+  "`bookmark-alist', filtered to retain only snippet bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-snippet-bookmark-p bookmark-alist))
+
+(put 'bmkp-some-tags-alist-only 'bmkp-read-arg 'bmkp-read-tags-completing)
+(defun bmkp-some-tags-alist-only (tags)
+  "`bookmark-alist', but with only bookmarks having some tags in TAGS.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not (lexical-let ((tgs  tags))
+                        (lambda (bmk)
+                          (bmkp-some (lexical-let ((bk  bmk)) (lambda (tag) (bmkp-has-tag-p bk tag)))
+                                     tgs)))
+                      bookmark-alist))
+
+(put 'bmkp-some-tags-regexp-alist-only 'bmkp-read-arg 'bmkp-read-regexp)
+(defun bmkp-some-tags-regexp-alist-only (regexp)
+  "`bookmark-alist', but with only bookmarks having some tags match REGEXP.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not (lexical-let ((rg  regexp))
+                        (lambda (bmk)
+                          (bmkp-some (lambda (tag) (bmkp-string-match-p rg (bmkp-tag-name tag)))
+                                     (bmkp-get-tags bmk))))
+                      bookmark-alist))
+
+(put 'bmkp-specific-buffers-alist-only 'bmkp-read-arg 'bmkp-read-buffers)
+(defun bmkp-specific-buffers-alist-only (&optional buffers)
+  "`bookmark-alist', filtered to retain only bookmarks to buffers BUFFERS.
+BUFFERS is a list of buffer names.
+It defaults to a singleton list with the current buffer's name.
+A new list is returned (no side effects).
+
+Note: Bookmarks created by vanilla Emacs do not record the buffer
+name.  They are therefore excluded from the returned alist."
+  (unless buffers  (setq buffers  (list (buffer-name))))
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not (lexical-let ((bufs  buffers))
+                        (lambda (bmk)
+                          (and (not (bmkp-desktop-bookmark-p       bmk)) ; Exclude these
+                               (not (bmkp-bookmark-file-bookmark-p bmk))
+                               (not (bmkp-sequence-bookmark-p      bmk))
+                               (not (bmkp-function-bookmark-p      bmk))
+                               (not (bmkp-variable-list-bookmark-p bmk))
+                               (member (bmkp-get-buffer-name bmk) bufs))))
+                      bookmark-alist))
+
+(put 'bmkp-specific-files-alist-only 'bmkp-read-arg 'bmkp-read-files)
+(defun bmkp-specific-files-alist-only (&optional files)
+  "`bookmark-alist', filtered to retain only bookmarks to files FILES.
+FILES is a list of absolute file names.
+It defaults to a singleton list with the current buffer's file name,
+ or to the empty list if the buffer is not visiting a file.
+A new list is returned (no side effects)."
+  (unless files  (setq files  (and (buffer-file-name)  (list (buffer-file-name)))))
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not (lexical-let ((ff  files))
+                        (lambda (bmk)
+                          (let ((bf  (bookmark-get-filename bmk))) 
+                            (and bf
+                                 ;; If we loaded `cl-seq.el': (cl-member bf ff :test #'bmkp-same-file-p)
+                                 (catch 'bmkp-specific-files-alist-only
+                                   (dolist (f  ff)
+                                     (or (bmkp-same-file-p f bf)  (throw 'bmkp-specific-files-alist-only nil)))
+                                   t)))))
+                      bookmark-alist))
+
+(defun bmkp-tagged-alist-only ()
+  "`bookmark-alist', with only bookmarks that have tags.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-get-tags bookmark-alist))
+
+(defun bmkp-temporary-alist-only ()
+  "`bookmark-alist', filtered to retain only temporary bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-temporary-bookmark-p bookmark-alist))
+
+(defun bmkp-this-file/buffer-alist-only ()
+  "`bookmark-alist', with only bookmarks for the current file/buffer.
+A new list is returned (no side effects).
+If visiting a file, this is `bmkp-this-file-alist-only'.
+Otherwise, this is `bmkp-this-buffer-alist-only'."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not (if (buffer-file-name) #'bmkp-this-file-p #'bmkp-this-buffer-p) bookmark-alist))
+
+(defun bmkp-this-buffer-alist-only ()
+  "`bookmark-alist', with only bookmarks for the current buffer.
+A new list is returned (no side effects).
+See `bmkp-this-buffer-p'."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-this-buffer-p bookmark-alist))
+
+(defun bmkp-this-file-alist-only ()
+  "`bookmark-alist', with only bookmarks for the current file.
+A new list is returned (no side effects).
+See `bmkp-this-file-p'."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-this-file-p bookmark-alist))
+
+(defun bmkp-unmarked-bookmarks-only ()
+  "Return the list of unmarked bookmarks."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if #'bmkp-marked-bookmark-p bookmark-alist))
+
+(defun bmkp-untagged-alist-only ()
+  "`bookmark-alist', with only bookmarks that do not have tags.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if #'bmkp-get-tags bookmark-alist))
+
+(defun bmkp-url-alist-only ()
+  "`bookmark-alist', filtered to retain only URL bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-url-bookmark-p bookmark-alist))
+
+(defun bmkp-url-browse-alist-only ()
+  "`bookmark-alist', but with only URL bookmarks that are non-W3M, non-EWW.
+\(The bookmarks satisfy `bmkp-url-browse-bookmark-p'.)
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-url-browse-bookmark-p bookmark-alist))
+
+(defun bmkp-variable-list-alist-only ()
+  "`bookmark-alist', filtered to retain only variable-list bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-variable-list-bookmark-p bookmark-alist))
+
+(defun bmkp-w3m-alist-only ()
+  "`bookmark-alist', filtered to retain only W3M bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not #'bmkp-w3m-bookmark-p bookmark-alist))
+
+;; This provides the `defvar's for all Bookmark+ history variables.
+;; Use this again, after you define any of your own filter functions
+;; `bmkp-*-alist-only', for new kinds of bookmarks.
+;;
+(bmkp-define-history-variables) ; Macro defined in `bookmark+-mac.el'.
+
+
+;;(@* "Miscellaneous Bookmark+ Functions")
+;;  *** Miscellaneous Bookmark+ Functions ***
+
+(if (fboundp 'find-tag-default-as-regexp)
+    (defun bmkp-read-regexp (&optional prompt defaults history)
+      "Same as `read-regexp', except argument PROMPT is optional.
+PROMPT defaults to \"Regexp: \"."
+      (unless prompt (setq prompt  "Regexp: "))
+      (read-regexp prompt defaults history))
+
+  ;; Same as `icicle-find-tag-default-as-regexp' in `icicles-fn.el'.
+  (defun bmkp-find-tag-default-as-regexp () ; Emacs < 24.3
+    "Return a regexp that matches the default tag at point.
+If there is no tag at point, return nil.
+
+When in a major mode that does not provide its own
+`find-tag-default-function', return a regexp that matches the
+symbol at point exactly."
+    (let* ((tagf  (or find-tag-default-function
+                      (get major-mode 'find-tag-default-function)
+                      'find-tag-default))
+           (tag   (funcall tagf)))
+      (and tag  (if (eq tagf 'find-tag-default)
+                    (format "\\_<%s\\_>" (regexp-quote tag))
+                  (regexp-quote tag)))))
+
+  ;; Same as `icicle-read-regexp' in `icicles-fn.el'.
+  (if (fboundp 'find-tag-default)
+      (defun bmkp-read-regexp (&optional prompt default history) ; Emacs 22-24.2
+        "Read and return a regular expression as a string.
+If PROMPT does not end with a colon and possibly whitespace then
+append \": \" to it.
+
+PROMPT defaults to \"Regexp: \".
+
+Optional argument DEFAULT is a string or a list of the form
+\(DEFLT . SUGGESTIONS), where DEFLT is a string or nil.
+
+The string DEFAULT or DEFLT is added to the prompt and is returned as
+the default value if the user enters empty input.  The empty string is
+returned if DEFAULT or DEFLT is nil and the user enters empty input.
+
+SUGGESTIONS is used only for Emacs 23 and later.  It is a list of
+strings that can be inserted into the minibuffer using `\\<minibuffer-local-map>\\[next-history-element]'.
+The values supplied in SUGGESTIONS are prepended to the list of
+standard suggestions, which include the tag at point, the last isearch
+regexp, the last isearch string, and the last replacement regexp.
+
+Optional argument HISTORY is a symbol to use for the history list.
+If nil then use `regexp-history'."
+        (unless prompt (setq prompt  "Regexp: "))
+        (let* ((deflt                  (if (consp default) (car default) default))
+               (suggestions            (and (> emacs-major-version 22)
+                                            (if (listp default) default (list default))))
+               (suggestions            (and (> emacs-major-version 22)
+                                            (append
+                                             suggestions
+                                             (list (bmkp-find-tag-default-as-regexp)
+                                                   (car regexp-search-ring)
+                                                   (regexp-quote (or (car search-ring)  ""))
+                                                   (car (symbol-value query-replace-from-history-variable))))))
+               (suggestions            (and (> emacs-major-version 22)
+                                            (delete-dups (delq nil (delete "" suggestions)))))
+               (history-add-new-input  nil) ; Do not automatically add default to history for empty input.
+               (input                  (read-from-minibuffer
+                                        (cond ((bmkp-string-match-p ":[ \t]*\\'" prompt) prompt)
+                                              (deflt (format "%s (default %s): " prompt
+                                                             (query-replace-descr deflt)))
+                                              (t (format "%s: " prompt)))
+                                        nil nil nil (or history  'regexp-history) suggestions t)))
+          (if (equal input "")
+              (or deflt  input)         ; Return the default value when the user enters empty input.
+            (prog1 input                ; Add non-empty input to the history and return input.
+              (add-to-history (or history  'regexp-history) input)))))
+
+    (defun bmkp-read-regexp (&optional prompt default history) ; Emacs 20-21
+      "Read and return a string.
+PROMPT defaults to \"Regexp: \".
+Optional arg DEFAULT is a string that is returned when the user enters
+empty input.  It can also be a list of strings, of which only the
+first is used.
+Optional arg HISTORY is a symbol to use for the history list.  If nil,
+use `regexp-history'."
+      (unless prompt (setq prompt  "Regexp: "))
+      (when (consp default) (setq default  (car default)))
+      (read-string (cond ((bmkp-string-match-p ":[ \t]*\\'" prompt) prompt)
+                         (default (format "%s (default %s): " prompt
+                                          (mapconcat #'isearch-text-char-description default "")))
+                         (t (format "%s: " prompt)))
+                   nil (or history  'regexp-history) default))))
+
+;; Same as `icicle-propertize'.  (Not used yet.)
+;;
+(defun bmkp-propertize (object &rest properties)
+  "Like `propertize', but for all Emacs versions.
+If OBJECT is not a string, then use `prin1-to-string' to get a string."
+  (let ((new  (if (stringp object) (copy-sequence object) (prin1-to-string object))))
+    (add-text-properties 0 (length new) properties new)
+    new))
+
+(defun bmkp-new-bookmark-default-names (&optional first-def)
+  "Return a list of default names (strings) for a new bookmark.
+A non-nil optional arg FIRST-DEF is prepended to the list of names
+described below.
+
+If the region is active and non-empty, then the first default name
+\(other than FIRST-DEF) is the current buffer name followed by \": \"
+and the region prefix (up to `bmkp-bookmark-name-length-max' chars).
+The other names are as described below.
+
+Uses option `bmkp-new-bookmark-default-names' to come up with the
+other names.  To these names, `bookmark-current-bookmark' and
+`bookmark-buffer-name' are appended, if available (non-nil).
+
+NOTE: For Emacs versions prior to Emacs 23, return only a single
+default name, not a list of names.  The name is the first in the list
+of names described above for Emacs 23+."
+  (let ((defs  (and first-def  (list first-def)))
+        val)
+    (unless (and (< emacs-major-version 23)  defs) ; Just use FIRST-DEF for Emacs < 23.
+      ;; If region is active, first default is its text, with buffer name prepended.
+      (when (and transient-mark-mode  mark-active  (> (region-end) (region-beginning)))
+        (let* ((regname  (concat (buffer-name) ": " (buffer-substring (region-beginning) (region-end))))
+               (defname  (bmkp-replace-regexp-in-string
+                          "\n" " "
+                          (progn (save-excursion (goto-char (region-beginning))
+                                                 (skip-chars-forward " ")
+                                                 (setq bookmark-yank-point  (point)))
+                                 (substring regname 0 (min bmkp-bookmark-name-length-max
+                                                           (length regname)))))))
+          (if (< emacs-major-version 23) (setq defs  defname) (add-to-list 'defs defname))))
+      ;; Names provided by option `bmkp-new-bookmark-default-names',
+      ;; plus `bookmark-current-bookmark' and `bookmark-buffer-name'.
+      (unless (and (< emacs-major-version 23)  defs)
+        (catch 'bmkp-new-bookmark-default-names
+          (dolist (fn  bmkp-new-bookmark-default-names)
+            (when (functionp fn)        ; Be sure it is defined and is a function.
+              (setq val  (funcall fn))
+              (when (and (stringp val)  (not (string= "" val)))
+                (setq val  (bmkp-replace-regexp-in-string "\n" " " val))
+                (if (> emacs-major-version 22)
+                    (add-to-list 'defs val)
+                  (throw 'bmkp-new-bookmark-default-names (setq defs  val)))))))
+        (when (and (< emacs-major-version 23)  (null defs))
+          (setq defs  (or bookmark-current-bookmark  (bookmark-buffer-name))))
+        (when (listp defs)
+          (when bookmark-current-bookmark (push bookmark-current-bookmark defs))
+          (let ((buf  (bookmark-buffer-name))) (when buf (push buf defs)))
+          (setq defs  (nreverse defs)))))
+    defs))
+
+(defun bmkp-bookmark-record-from-name (bookmark-name &optional noerror memp alist)
+  "Return the full bookmark (record) that corresponds to BOOKMARK-NAME.
+BOOKMARK-NAME must be a string.  If it has non-nil text property
+`bmkp-full-record' then use that.  Otherwise, look for the first
+bookmark in ALIST that has the given name.
+
+Non-nil optional arg NOERROR means return nil if BOOKMARK-NAME does
+not name a valid bookmark or is valid but is not in ALIST.  If NOERROR
+is nil then raise an error in this case.
+
+Non-nil optional arg MEMP means that if property `bmkp-full-record' is
+available then look up its value (the full bookmark) in ALIST, testing
+with `eq'.  If that record is not in ALIST, return nil.
+
+Optional arg ALIST defaults to `bookmark-alist'."
+  (unless alist (setq alist  bookmark-alist))
+  (let ((full  (get-text-property 0 'bmkp-full-record bookmark-name)))
+    (or (and full
+             (or (not memp)  (memq full alist))
+             full)
+        ;; Punt: return first matching bookmark in ALIST.
+        (if (fboundp 'assoc-string)     ; Emacs 22+.  Use `assoc-string' for its CASE-FOLD arg.
+            (assoc-string bookmark-name alist bookmark-completion-ignore-case)
+          (assoc bookmark-name alist))
+        (and (not noerror)  (error "No such bookmark in bookmark list: `%s'" bookmark-name)))))
+
+(defun bmkp-rename-for-marked-and-omitted-lists (old new)
+  "Replace OLD bookmark name with NEW in marked and omitted lists."
+  (when (bmkp-marked-bookmark-p old)
+    (setq bmkp-bmenu-marked-bookmarks  (bmkp-delete-bookmark-name-from-list old
+                                                                            bmkp-bmenu-marked-bookmarks))
+    (push new bmkp-bmenu-marked-bookmarks))
+  (when (bmkp-omitted-bookmark-p old)
+    (setq bmkp-bmenu-omitted-bookmarks  (bmkp-delete-bookmark-name-from-list old
+                                                                             bmkp-bmenu-omitted-bookmarks))
+    (push new bmkp-bmenu-omitted-bookmarks)))
+
+(defun bmkp-get-bookmark-in-alist (bookmark &optional noerror alist)
+  "Return the full bookmark in ALIST that corresponds to BOOKMARK.
+Return nil if there is none.
+BOOKMARK is a bookmark name or a bookmark record.
+
+Non-nil optional arg NOERROR means return nil if BOOKMARK does not
+represent a valid bookmark or is valid but is not in ALIST.  If
+NOERROR is nil then raise an error in this case.
+
+Optional arg ALIST defaults to `bookmark-alist'.
+
+Bookmark membership in ALIST is tested using `eq'.
+
+If BOOKMARK is a bookmark name instead of a full bookmark then return
+what `bmkp-bookmark-record-from-name' with non-nil arg MEMP returns.
+
+This function is like `bookmark-get-bookmark', except that
+`bookmark-get-bookmark' tests whether BOOKMARK is in `bookmark-alist'
+only when it is a string (a bookmark name, not a full bookmark).  When
+BOOKMARK is a full bookmark `bookmark-get-bookmark' is thus not a test
+for its existence, as is `bmkp-get-bookmark-in-alist'."
+  (cond ((consp bookmark) (and (memq bookmark (or alist  bookmark-alist))  bookmark))
+        ((stringp bookmark) (bmkp-bookmark-record-from-name bookmark noerror 'MEMP alist))
+        (t (and (not noerror)  (error "Invalid bookmark: `%s'" bookmark)))))
+
+(defun bmkp-default-bookmark-file ()
+  "`bmkp-last-as-first-bookmark-file', or `bookmark-default-file' if nil."
+  (or bmkp-last-as-first-bookmark-file  bookmark-default-file))
+
+(defun bmkp-completing-read-bookmarks (&optional alist pred hist names-only-p use-nil-alist-p)
+  "Read bookmark names and return the bookmarks named as a list.
+You are prompted for each bookmark name.  Hit `RET' with empty input
+to end.
+
+ALIST is the bookmark alist to use.  It defaults to `bookmark-alist'
+unless USE-NIL-ALIST-P is non-nil.
+
+NAMES-ONLY-P non-nil means return bookmark names, not full bookmarks.
+If NAMES-ONLY-P is `lax' then completion is lax.
+
+USE-NIL-ALIST-P means do not default ALIST to `bookmark-alist': if
+ALIST is nil there are no bookmark candidates, so just return nil."
+  (let ((bmks  ())
+        (bmk   t))
+    (if (and use-nil-alist-p  (not alist))
+        ()
+      (while bmk
+        (setq bmk  (bmkp-completing-read-1 "Bookmark (RET for each, empty input to finish)"
+                                           "" alist pred hist (eq names-only-p 'lax)))
+        (when (equal "" bmk) (setq bmk  nil))
+        (when (and bmk  (not names-only-p)) (setq bmk (bmkp-get-bookmark-in-alist bmk 'NO-ERROR alist)))
+        (when bmk (push bmk bmks)))
+      (setq bmks  (nreverse bmks))
+      bmks)))
+
+(defun bmkp-completing-read-lax (prompt &optional default alist pred hist use-nil-alist-p)
+  "Read a bookmark name, prompting with PROMPT.
+Like `bookmark-completing-read', but completion is lax (non-strict):
+your input need not match any existing bookmark name.
+
+In addition:
+ * You can use `SPC' and `?' freely when typing the name.
+ * You can use `C-M-w' repeatedly to yank consecutive words from the
+   current buffer (see `bookmark-yank-word')."
+  (let ((orig-C-M-w  (lookup-key minibuffer-local-completion-map (kbd "C-M-w")))
+        (orig-C-M-u  (lookup-key minibuffer-local-completion-map (kbd "C-M-u")))
+        (orig-SPC    (lookup-key minibuffer-local-completion-map (kbd "SPC")))
+        (orig-qmark  (lookup-key minibuffer-local-completion-map (kbd "?"))))
+    (unwind-protect
+        (progn (define-key minibuffer-local-completion-map (kbd "C-M-w") 'bookmark-yank-word)
+               (define-key minibuffer-local-completion-map (kbd "C-M-u") 'bookmark-insert-current-bookmark)
+               (unless (and (boundp 'icicle-mode)  icicle-mode
+                            (eq orig-SPC 'icicle-self-insert))
+                 (define-key minibuffer-local-completion-map (kbd "SPC") 'self-insert-command))
+               (unless (and (boundp 'icicle-mode)  icicle-mode
+                            (eq orig-qmark 'icicle-self-insert))
+                 (define-key minibuffer-local-completion-map   (kbd "?") 'self-insert-command))
+               (bmkp-completing-read-1 prompt default alist pred hist 'LAX use-nil-alist-p))
+      (define-key minibuffer-local-completion-map (kbd "C-M-w") orig-C-M-w)
+      (define-key minibuffer-local-completion-map (kbd "C-M-u") orig-C-M-u)
+      (define-key minibuffer-local-completion-map (kbd "SPC")   orig-SPC)
+      (define-key minibuffer-local-completion-map (kbd "?")     orig-qmark))))
+
+(defun bmkp-completing-read-1 (prompt &optional default alist pred hist laxp use-nil-alist-p)
+  "Helper for functions that read a bookmark name with completion.
+See `bookmark-completing-read' for the argument descriptions."
+  (bookmark-maybe-load-default-file)
+  (unless (or alist  use-nil-alist-p) (setq alist  bookmark-alist))
+  (if (and (not laxp)
+           (listp last-nonmenu-event)
+           (or (eq t bmkp-menu-popup-max-length)
+               (and (integerp bmkp-menu-popup-max-length)  (< (length alist) bmkp-menu-popup-max-length))))
+      (bookmark-menu-popup-paned-menu
+       t prompt
+       (if bmkp-sort-comparer           ; Test whether to sort, but always use `string-lessp'.
+           (sort (bookmark-all-names alist) 'string-lessp)
+         (bookmark-all-names alist)))
+    (let* ((icicle-delete-candidate-object  (lambda (cand) ; For `S-delete' in Icicles.
+                                              (bookmark-delete (icicle-transform-multi-completion cand))))
+           (icicle-bookmark-completing-p    t)
+           (completion-ignore-case          bookmark-completion-ignore-case)
+           (default                         (and (not (equal "" default))  default)) ; Treat "" like nil.
+           (default                         (if (and (consp default)  (< emacs-major-version 23))
+                                                (car default)
+                                              default))
+           (prompt                          (concat prompt (if default
+                                                               (format " (%s): " (if (consp default)
+                                                                                     (car default)
+                                                                                   default))
+                                                             ": ")))
+           (str                             (completing-read prompt alist pred (not laxp) nil
+                                                             (or hist  'bookmark-history) default)))
+      str)))
+
+(defun bmkp-jump-1 (bookmark display-function &optional flip-use-region-p)
+  "Helper function for `bookmark-jump' commands.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a bookmark name then it is looked up in `bookmark-alist'.
+If it is a record then it is NOT looked up (need not belong).
+If it is or has a name that has non-nil property `bmkp-full-record',
+then use the bookmark in `bookmark-alist' that is the value of that
+property.  Raise no error if it has no name.
+
+DISPLAY-FUNCTION as in `bmkp-jump'.  Passed to `bookmark--jump-via'.
+Non-nil optional arg FLIP-USE-REGION-P means temporarily flip the
+ value of `bmkp-use-region'."
+  (setq bookmark  (bmkp-get-bookmark bookmark 'NOERROR))
+  (unless bookmark (error "No bookmark specified"))
+  (run-hooks 'bmkp-before-jump-hook)
+  (bookmark-maybe-historicize-string (bmkp-bookmark-name-from-record bookmark))
+  (let ((bmkp-use-region  (if flip-use-region-p (not bmkp-use-region) bmkp-use-region)))
+    (bookmark--jump-via bookmark display-function)))
+
+(defun bmkp-select-buffer-other-window (buffer)
+  "Select BUFFER in another window.
+If `bmkp-other-window-pop-to-flag' is non-nil, then use
+`pop-to-buffer'.  Otherwise, use `switch-to-buffer-other-window'."
+  (if bmkp-other-window-pop-to-flag (pop-to-buffer buffer t) (switch-to-buffer-other-window buffer)))
+
+(defun bmkp-maybe-save-bookmarks (&optional same-count-p)
+  "Increment save counter and maybe save `bookmark-alist'.
+Non-nil optional arg SAME-COUNT-P means do not increment
+`bookmark-alist-modification-count'."
+  (unless same-count-p (setq bookmark-alist-modification-count  (1+ bookmark-alist-modification-count)))
+  (when (bookmark-time-to-save-p) (bookmark-save)))
+
+;;;###autoload (autoload 'bmkp-annotate-bookmark "bookmark+")
+(defun bmkp-annotate-bookmark (bookmark) ; Bound to `C-x x a a'
+  "Annotate BOOKMARK.  Pop up a buffer to add or edit the annotation.
+Interactively, this is the same as using command
+`bookmark-edit-annotation' with a prefix arg.  You are prompted for
+the bookmark name.  Command `bookmark-edit-annotation' can be more
+convenient for editing an existing annotation, because you choose
+among only the already annotated bookmarks, not all bookmarks.
+
+Non-interactively, BOOKMARK is a bookmark name or a bookmark record."
+  (interactive (list (bookmark-completing-read "Annotate bookmark" (bmkp-default-bookmark-name))))
+  (pop-to-buffer (generate-new-buffer-name "*Bookmark Annotation Compose*"))
+  (bookmark-insert-annotation bookmark)
+  (bookmark-edit-annotation-mode)
+  (setq bookmark-annotation-name  bookmark))
+
+;;;###autoload (autoload 'bmkp-annotate-bookmark-this-file/buffer "bookmark+")
+(defun bmkp-annotate-bookmark-this-file/buffer (bookmark) ; Bound to `C-x x a b'
+  "Annotate an existing bookmark in this file or buffer.
+You are prompted for the name of a bookmark here, with completion."
+  (interactive
+   (let ((alist  (bmkp-this-file/buffer-alist-only)))
+     (list (bookmark-completing-read (format "%s annotation for bookmark"
+                                             (if current-prefix-arg "Add or edit" "Edit"))
+                                     (or (and (fboundp 'bmkp-bookmarks-lighted-at-point)
+                                              (bmkp-bookmarks-lighted-at-point))
+                                         (bmkp-default-bookmark-name alist))
+                                     alist
+                                     nil
+                                     nil
+                                     (not current-prefix-arg)))))
+  (bookmark-edit-annotation bookmark))
+
+;;;###autoload (autoload 'bmkp-annotate-all-bookmarks-this-file/buffer "bookmark+")
+(defun bmkp-annotate-all-bookmarks-this-file/buffer () ; Bound to `C-x x a B'
+  "Pop up annotation-editing buffer for each bookmark in this file/buffer."
+  (interactive)
+  (dolist (bmk  (bmkp-this-file/buffer-alist-only))
+    (bookmark-edit-annotation bmk)))
+
+;;;###autoload (autoload 'bmkp-show-this-annotation-read-only "bookmark+")
+(defun bmkp-show-this-annotation-read-only ()
+  "Switch to `Show Bookmark Annotation' mode for this annotation.
+That is, switch from edit mode to read-only mode."
+  (interactive)
+  (unless (eq major-mode 'bookmark-edit-annotation-mode)
+    (error "Buffer is not in `Edit Bookmark Annotation' mode"))
+  (if (not (or (not (buffer-modified-p))  (y-or-n-p "Annotation was modified.  Lose changes?")))
+      (message "OK, canceled - use `C-c C-c' if you want to save changes")
+    (let* ((bmk    (bmkp-get-bookmark bookmark-annotation-name 'NOERROR))
+           (bname  (bookmark-name-from-full-record bmk))
+           (ann    (and bmk  (bookmark-get-annotation bmk)))
+           (obuf   (current-buffer)))
+      (unless bname (error "No such bookmark: `%s'" bmk))
+      (bmkp--pop-to-buffer-same-window (format "*`%s' Annotation*" bname))
+      (let ((buffer-read-only  nil)     ; Because buffer might already exist, in view mode.
+            (buf-modified-p    (buffer-modified-p)))
+        (delete-region (point-min) (point-max))
+        (insert (concat "Annotation for bookmark '" bname "':\n\n"))
+        ;; Use `font-lock-ignore' property from library `font-lock+.el', because Org mode
+        ;; uses font-lock, which would otherwise wipe out the highlighting added here.
+        (add-text-properties (line-beginning-position -1) (line-end-position 1)
+                             '(face              bmkp-heading
+                               font-lock-ignore  t))
+        (insert ann)
+        (set-buffer-modified-p buf-modified-p))
+      (goto-char (point-min))
+      (bookmark-show-annotation-mode)
+      (when (fboundp 'fit-frame-if-one-window) (fit-frame-if-one-window))
+      (setq bookmark-annotation-name  bmk)
+      (kill-buffer obuf))))
+
+;;;###autoload (autoload 'bmkp-edit-this-annotation "bookmark+")
+(defun bmkp-edit-this-annotation ()
+  "Switch to `Edit Bookmark Annotation' mode for this annotation.
+That is, switch from read-only mode to edit mode."
+  (interactive)
+  (unless (eq major-mode 'bookmark-show-annotation-mode)
+    (error "Buffer is not in `Show Bookmark Annotation' mode"))
+  (let* ((bmk    (bmkp-get-bookmark bookmark-annotation-name 'NOERROR))
+         (bname  (bookmark-name-from-full-record bmk))
+         (obuf   (current-buffer)))
+    (unless bname (error "No such bookmark: `%s'" bmk))
+    (bmkp--pop-to-buffer-same-window (generate-new-buffer-name "*Bookmark Annotation Compose*"))
+    (let ((buf-modified-p  (buffer-modified-p)))
+      (bookmark-insert-annotation bname)
+      (set-buffer-modified-p buf-modified-p))
+    (bookmark-edit-annotation-mode)
+    (when (fboundp 'fit-frame-if-one-window) (fit-frame-if-one-window))
+    (setq bookmark-annotation-name  bmk)
+    (kill-buffer obuf)))
+
+;;;###autoload (autoload 'bmkp-copy-bookmark "bookmark+")
+(defalias 'bmkp-copy-bookmark 'bmkp-clone-bookmark)
+;;;###autoload (autoload 'bmkp-clone-bookmark "bookmark+")
+(defun bmkp-clone-bookmark (bookmark &optional clone confirm-overwrite-p)
+                                        ; Bound to `C-x x 2' (`M-n' in bookmark list)
+  "Duplicate BOOKMARK to produce a clone.
+The clone name is the same as BOOKMARK, but with \"<2>\" appended.
+With a prefix arg you are instead prompted for the clone name.
+
+When called from Lisp:
+ * BOOKMARK is a bookmark name or a bookmark record.
+ * Optional CLONE is the clone name.
+ * Optional non-nil CONFIRM-OVERWRITE-P means prompt to confirm overwriting an existing bookmark."
+  (interactive
+   (let* ((orig     (bookmark-completing-read "Clone bookmark" (bmkp-default-bookmark-name)))
+          ;; Remove any `bmkp-full-record' property from name.
+          (_IGNORE  (remove-text-properties 0 (length orig) '(bmkp-full-record nil) orig))
+          (default  (concat orig "<2>"))
+          (new      (if current-prefix-arg
+                        (bmkp-completing-read-lax "Clone name" default)
+                      default)))
+     (while (equal orig new)
+       (setq new  (bmkp-completing-read-lax "Clone name (must be different)" default)))
+     ;; Remove any `bmkp-full-record' property from name.
+     (remove-text-properties 0 (length new) '(bmkp-full-record nil) new)
+     (list orig new t)))
+  (let ((orig-bmk  (bmkp-get-bookmark bookmark))
+        (new-bmk   (bmkp-get-bookmark clone 'NO-ERROR)))
+    (when (and new-bmk  confirm-overwrite-p)
+      (unless (yes-or-no-p "Another bookmark with that name already exists.  Overwrite it? ")
+        (error "OK; canceled")))
+    (setq new-bmk  (copy-sequence orig-bmk))
+    ;; Get rid of old bookmark name, which might have property `bmkp-full-record'.
+    ;; Need to do that before calling `bookmark-store'.
+    (setcar new-bmk clone)
+    (bookmark-store clone (cdr new-bmk) nil) ; (Puts `bmkp-full-record' on name.)
+    (setq bookmark-current-bookmark  clone)
+    (if (and (get-buffer bmkp-bmenu-buffer)  (get-buffer-window (get-buffer bmkp-bmenu-buffer) 0))
+        (with-current-buffer (get-buffer bmkp-bmenu-buffer)
+          (bmkp-refresh-menu-list clone))
+      (bookmark-bmenu-surreptitiously-rebuild-list))
+    (bmkp-maybe-save-bookmarks)))
+
+;;;###autoload (autoload 'bmkp-edit-bookmark-name-and-location "bookmark+")
+(defun bmkp-edit-bookmark-name-and-location (bookmark &optional edit-record-p)
+                                        ; Bound to `C-x x r' (`r' in bookmark list)
+  "Edit BOOKMARK's name and location, and maybe save them.
+Return a list of the new bookmark name and new location.
+BOOKMARK is a bookmark name or a bookmark record.
+
+Without a prefix arg, you are prompted for the new bookmark name and
+ the new location name.  When entering the new names you can use
+ completion against existing names.  This completion is lax, so you
+ can easily edit an existing name.  See `bookmark-set' for particular
+ keys available during this input.
+
+With a prefix arg, edit the complete bookmark record (the
+ internal, Lisp form)."
+  (interactive
+   (list (bookmark-completing-read (concat "Edit " (and current-prefix-arg  "internal record for ")
+                                           "bookmark")
+                                   (bmkp-default-bookmark-name))
+         current-prefix-arg))
+  (setq bookmark  (bmkp-get-bookmark-in-alist bookmark))
+  (if edit-record-p
+      (bmkp-edit-bookmark-record bookmark)
+    (let* ((bmk-name                                    (bmkp-bookmark-name-from-record bookmark))
+           (bmk-location                                (bookmark-prop-get bookmark 'location))
+           (bmk-urlp                                    (and bmk-location
+                                                             (require 'ffap nil t)
+                                                             (ffap-url-p bmk-location)))
+           (bmk-filename                                (bookmark-get-filename bmk-name))
+           (bmk-buffname                                (or (bmkp-get-buffer-name bookmark)
+                                                            (bookmark-prop-get bookmark 'buffer)))
+           (new-bmk-name                                (bmkp-completing-read-lax
+                                                         "New bookmark name" bmk-name))
+           (icicle-unpropertize-completion-result-flag  t) ; For `read-file-name'.
+           (new-location
+            (cond (bmk-location
+                   (cond ((not bmk-urlp) (read-string "New location: "))
+                         ((and (featurep 'w3m)  (bmkp-w3m-bookmark-p bmk-name))
+                          (w3m-input-url "New URL: " bmk-location))
+                         ((and (fboundp 'bmkp-eww-bookmark-p)  (bmkp-eww-bookmark-p bmk-name))
+                          (read-string "New URL: "))
+                         ((require 'ffap) (ffap-read-file-or-url "New URL: " bmk-location))
+                         (t (read-string "New location: "))))
+                  (bmk-filename
+                   (if (and (featurep 'w3m)
+                            (bmkp-w3m-bookmark-p bmk-name))
+                       (w3m-input-url "New url: " bmk-filename)
+                     (read-file-name
+                      "New file name (location): "
+                      (and bmk-filename
+                           (file-name-directory  bmk-filename))
+                      bmk-filename)))
+                  (bmk-buffname
+                   (read-buffer "New location: " bmk-buffname))
+                  (t                    ; No current location.
+                   (read-string "New location: "))))
+           ;; $$$$$$ Should we change a W3M bookmark that uses `filename' to use `location' instead?
+           (changed-bmk-name-p                          (and (not (equal new-bmk-name ""))
+                                                             (not (equal new-bmk-name bmk-name))))
+           (changed-location-p                          (and bmk-location
+                                                             (not (equal new-location ""))
+                                                             (not (equal new-location bmk-location))))
+           (changed-filename-p                          (and bmk-filename
+                                                             (not (equal new-location ""))
+                                                             (not (equal new-location bmk-filename))))
+           (changed-buffname-p                          (and bmk-buffname
+                                                             (not (equal new-location ""))
+                                                             (not (equal new-location bmk-buffname))
+                                                             (not (and (fboundp 'bmkp-eww-bookmark-p)
+                                                                       (bmkp-eww-bookmark-p bookmark))))))
+      (when (or changed-bmk-name-p  changed-location-p  changed-filename-p  changed-buffname-p)
+        (when changed-bmk-name-p (bookmark-rename bmk-name new-bmk-name 'BATCHP))
+        (when changed-location-p (bookmark-prop-set new-bmk-name 'location new-location))
+        (when changed-filename-p (bookmark-set-filename new-bmk-name new-location))
+        (when changed-buffname-p (bookmark-prop-set new-bmk-name 'buffer-name new-location))
+        ;; Change location for Dired too, but not if different from original file name (e.g. a cons).
+        (let ((dired-dir  (bookmark-prop-get new-bmk-name 'dired-directory)))
+          (when (and dired-dir  (equal dired-dir bmk-filename))
+            (bookmark-prop-set new-bmk-name 'dired-directory new-location)))
+        (bmkp-maybe-save-bookmarks)     ; Maybe save automatically.
+        (when (and bookmark-alist-modification-count ; Did not save automatically.  Ask user.
+                   (y-or-n-p "Save changes? "))
+          (bookmark-save))
+        (list new-bmk-name new-location)))))
+
+(define-derived-mode bmkp-edit-bookmark-records-mode emacs-lisp-mode
+    "Edit Bookmark Records"
+  "Mode for editing a list of bookmark records, as in `bookmark-alist'.
+When you finish editing, use \\<bmkp-edit-bookmark-record-mode-map>\
+`\\[bmkp-edit-bookmark-record-send]' in the record-editing buffer."
+  :group 'bookmark-plus)
+
+;; This binding must be defined *after* the mode, so `bmkp-edit-bookmark-records-mode-map' is defined.
+;; (Alternatively, we could use a `defvar' to define `bmkp-edit-bookmark-records-mode-map' before
+;; calling `define-derived-mode'.)
+(define-key bmkp-edit-bookmark-records-mode-map "\C-c\C-c" 'bmkp-edit-bookmark-records-send)
+
+(defvar bmkp-edit-bookmark-records-number 0
+  "NUmber of bookmard records being edited.")
+
+;;;###autoload (autoload 'bmkp-edit-bookmark-records-send "bookmark+")
+(defun bmkp-edit-bookmark-records-send (&optional msg-p) ; Bound to `C-c C-c' in records-editing buffer.
+  "Update `bookmark-alist' with buffer contents: a bookmark alist.
+Lines beginning with `;;' are ignored.
+Non-interactively, optional arg MSG-P means display progress messages.
+
+This assumes that the bookmarks in the buffer are the marked bookmarks
+in `*Bookmark List*'.  That is, it assumes that the buffer was created
+by `bmkp-bmenu-edit-marked' (`\\<bookmark-bmenu-mode-map>\\[bmkp-bmenu-edit-marked]' in `*Bookmark List*')."
+  (interactive "p")
+  (unless (eq major-mode 'bmkp-edit-bookmark-records-mode)
+    (error "Not in `bmkp-edit-bookmark-records-mode'"))
+  (when msg-p (message "Reading edited bookmarks..."))
+  (let* ((editbuf             (current-buffer))
+         (orig-bmks           (bmkp-marked-bookmarks-only))
+         (edited-bookmarks    ())
+         (read-error-msg
+          (catch 'bmkp-edit-bookmark-records-send
+            (setq edited-bookmarks  (condition-case err
+                                        (save-excursion (goto-char (point-min))  (read (current-buffer)))
+                                      (error (throw 'bmkp-edit-bookmark-records-send
+                                               (error-message-string err)))))
+            (unless orig-bmks (error "No marked bookmarks now - edits must correspond to currently marked"))
+            (cond ((not (listp edited-bookmarks))
+                   (throw 'bmkp-edit-bookmark-records-send "Not a list of bookmarks"))
+                  ((not (= (length edited-bookmarks) bmkp-edit-bookmark-records-number))
+                   (throw 'bmkp-edit-bookmark-records-send
+                     (format "Need %d bookmarks, but there seem to be %d"
+                             bmkp-edit-bookmark-records-number (length edited-bookmarks)))))
+            (let ((bookmark-save-flag  (and (not bmkp-count-multi-mods-as-one-flag)
+                                            bookmark-save-flag))) ; Save only after `dolist' and update.
+              (dolist (edited-bmk  edited-bookmarks)
+                (unless (and (consp edited-bmk)  (stringp (car edited-bmk))) ; Sanity check.
+                  (throw 'bmkp-edit-bookmark-records-send (format "Invalid bookmark: `%s'" edited-bmk)))
+                (let ((bname  (bmkp-bookmark-name-from-record edited-bmk))
+                      (data   (bmkp-bookmark-data-from-record edited-bmk)))
+                  ;; Put the full bookmark on its name as property `bmkp-full-record'.
+                  ;; Do this regardless of Emacs version and `bmkp-propertize-bookmark-names-flag'.
+                  ;; If it needs to be stripped, that will be done when saving.
+                  (put-text-property 0 (length bname) 'bmkp-full-record edited-bmk bname)
+                  ;; Update the original bookmark (same cons cell) with what's in the edited version.
+                  (setcar (car orig-bmks) bname)
+                  (setcdr (car orig-bmks) data)
+                  ;; This is the same as `add-to-list' with `EQ' (not available for Emacs 20-21).
+                  (unless (memq (car orig-bmks) bmkp-modified-bookmarks)
+                    (setq bmkp-modified-bookmarks  (cons (car orig-bmks) bmkp-modified-bookmarks)))
+                  (setq orig-bmks  (cdr orig-bmks))))
+              ;; Update using modified ORIG-BMKS.
+              (setq bmkp-bmenu-marked-bookmarks        (mapcar #'bmkp-bookmark-name-from-record
+                                                               bmkp-modified-bookmarks)
+                    bmkp-sorted-alist                  (bmkp-sort-omit bookmark-alist)
+                    bookmark-alist-modification-count  (1+ bookmark-alist-modification-count)))
+            nil)))
+    (if (stringp read-error-msg)
+        (if msg-p  (message "%s  --> edit and try again" read-error-msg)  (error read-error-msg))
+      (when (get-buffer editbuf) (kill-buffer editbuf))
+      (bmkp-refresh/rebuild-menu-list
+       (and (= 1 (length edited-bookmarks))  (car edited-bookmarks)) ; Only one, so we belong on its line.
+       (not msg-p)))))
+
+(define-derived-mode bmkp-edit-bookmark-record-mode emacs-lisp-mode
+    "Edit Bookmark Record"
+  "Mode for editing an internal bookmark record.
+When you finish editing, use \\<bmkp-edit-bookmark-record-mode-map>\
+`\\[bmkp-edit-bookmark-record-send]' in the record-editing buffer."
+  :group 'bookmark-plus)
+
+;; This binding must be defined *after* the mode, so `bmkp-edit-bookmark-record-mode-map' is defined.
+;; (Alternatively, we could use a `defvar' to define `bmkp-edit-bookmark-record-mode-map' before
+;; calling `define-derived-mode'.)
+(define-key bmkp-edit-bookmark-record-mode-map "\C-c\C-c" 'bmkp-edit-bookmark-record-send)
+
+;;;###autoload (autoload 'bmkp-edit-bookmark-record "bookmark+")
+(defun bmkp-edit-bookmark-record (bookmark) ; Bound to `C-x x E'.
+  "Edit the full record (the Lisp sexp) for BOOKMARK.
+BOOKMARK is a bookmark name or a bookmark record.
+When you finish editing, use \\<bmkp-edit-bookmark-record-mode-map>\
+`\\[bmkp-edit-bookmark-record-send]' in the record-editing buffer.
+The current bookmark list is then updated to reflect your edits."
+  (interactive (list (bookmark-completing-read "Edit Lisp record for bookmark" (bmkp-default-bookmark-name))))
+  (bookmark-maybe-load-default-file)
+  (setq bmkp-edit-bookmark-orig-record  (bmkp-get-bookmark-in-alist bookmark))
+  (let* ((bmk-copy  (copy-sequence bmkp-edit-bookmark-orig-record)) ; Shallow copy
+         (bname     (bmkp-bookmark-name-from-record bmk-copy))
+         (bufname   (format "*Edit Record for Bookmark `%s'*" bname)))
+    (set-text-properties 0 (length bname) nil bname) ; Strip properties from (copied) name string.
+    (bookmark-maybe-historicize-string bname)
+    (bmkp-with-output-to-plain-temp-buffer bufname
+      (princ
+       (substitute-command-keys
+        (concat ";; Edit the Lisp record for bookmark\n;;\n"
+                ";; `" bname "'\n;;\n"
+                ";; Type \\<bmkp-edit-bookmark-record-mode-map>\
+`\\[bmkp-edit-bookmark-record-send]' when done.\n;;\n")))
+      ;; (let ((print-circle  t)) (pp bmk)) ; $$$$$$ Binding should not really be needed now.
+      (pp bmk-copy)
+      (goto-char (point-min)))
+    (pop-to-buffer bufname)
+    (buffer-enable-undo)
+    (with-current-buffer (get-buffer bufname) (bmkp-edit-bookmark-record-mode))))
+
+;;;###autoload (autoload 'bmkp-edit-bookmark-record-send "bookmark+")
+(defun bmkp-edit-bookmark-record-send (&optional msg-p) ; Bound to `C-c C-c' in record-editing buffer.
+  "Update `bookmark-alist' with buffer contents: a bookmark record.
+Lines beginning with `;;' are ignored.
+Non-interactively, optional arg MSG-P means display progress messages."
+  (interactive "p")
+  (unless (eq major-mode 'bmkp-edit-bookmark-record-mode)
+    (error "Not in `bmkp-edit-bookmark-record-mode'"))
+  (unless (and (boundp 'bmkp-edit-bookmark-orig-record)  (consp bmkp-edit-bookmark-orig-record))
+    (error "Lost original bookmark record - try edit command again"))
+  (when msg-p (message "Reading edited bookmark..."))
+  (let* ((editbuf     (current-buffer))
+         (bmk-name    nil)
+         (read-error-msg
+          (catch 'bmkp-edit-bookmark-record-send
+            (let ((edited-bmk
+                   (condition-case err
+                       (save-excursion (goto-char (point-min))  (read (current-buffer)))
+                     (error (throw 'bmkp-edit-bookmark-record-send (error-message-string err))))))
+              (unless (and (consp edited-bmk)  (stringp (car edited-bmk)))
+                (throw 'bmkp-edit-bookmark-record-send (format "Invalid bookmark: `%s'" edited-bmk)))
+              (let ((bname  (bmkp-bookmark-name-from-record edited-bmk))
+                    (data   (bmkp-bookmark-data-from-record edited-bmk)))
+                ;; Put the full bookmark on its name as property `bmkp-full-record'.
+                ;; Do this regardless of Emacs version and `bmkp-propertize-bookmark-names-flag'.
+                ;; If it needs to be stripped, that will be done when saving.
+                (put-text-property 0 (length bname) 'bmkp-full-record edited-bmk bname)
+                ;; Update the original bookmark with what's in the edited version.
+                (setcar bmkp-edit-bookmark-orig-record bname)
+                (setcdr bmkp-edit-bookmark-orig-record data)
+                ;; This is the same as `add-to-list' with `EQ' (not available for Emacs 20-21).
+                (unless (memq bmkp-edit-bookmark-orig-record bmkp-modified-bookmarks)
+                  (setq bmkp-modified-bookmarks  (cons bmkp-edit-bookmark-orig-record
+                                                       bmkp-modified-bookmarks)))
+                (setq bmk-name  bname)) ; Save for bookmark-list display, below.
+              (setq bmkp-sorted-alist                  (bmkp-sort-omit bookmark-alist)
+                    bookmark-alist-modification-count  (1+ bookmark-alist-modification-count)))
+            nil)))
+    (if (stringp read-error-msg)
+        (if msg-p (message "%s  --> edit and try again" read-error-msg) (error read-error-msg))
+      (when (get-buffer editbuf) (kill-buffer editbuf))
+      (bmkp-refresh/rebuild-menu-list bmk-name (not msg-p)))
+    (unless read-error-msg
+      (setq bmkp-edit-bookmark-orig-record  nil)))) ; Reset it, but keep it if error so can try again.
+
+;;;###autoload (autoload 'bmkp-edit-bookmark-record-file/buffer "bookmark+")
+(defun bmkp-edit-bookmark-record-file/buffer (bookmark) ; Not bound
+  "Edit the full record (the Lisp sexp) of a bookmark in this buffer.
+You are prompted for the name of a bookmark here, with completion."
+  (interactive
+   (let ((alist  (bmkp-this-file/buffer-alist-only)))
+     (list (bookmark-completing-read (format "%s annotation for bookmark"
+                                             (if current-prefix-arg "Add or edit" "Edit"))
+                                     (or (and (fboundp 'bmkp-bookmarks-lighted-at-point)
+                                              (bmkp-bookmarks-lighted-at-point))
+                                         (bmkp-default-bookmark-name alist))
+                                     alist
+                                     nil
+                                     nil
+                                     (not current-prefix-arg)))))
+  (bmkp-edit-bookmark-record bookmark))
+
+;;; ;;;###autoload (autoload 'bmkp-edit-all-bookmark-records-this-file/buffer "bookmark+")
+;;; (defun bmkp-edit-all-bookmark-records-this-file/buffer () ; Not bound
+;;;   "Pop up a record-editing buffer for each bookmark in this file/buffer."
+;;;   (interactive)
+;;;   (dolist (bmk  (bmkp-this-file/buffer-alist-only))
+;;;     (bmkp-edit-bookmark-record bmk)))
+
+(define-derived-mode bmkp-edit-tags-mode emacs-lisp-mode
+    "Edit Bookmark Tags"
+  "Mode for editing bookmark tags.
+When you have finished composing, type \\[bmkp-edit-tags-send]."
+  :group 'bookmark-plus)
+
+;; This binding must be defined *after* the mode, so `bmkp-edit-tags-mode-map' is defined.
+;; (Alternatively, we could use a `defvar' to define `bmkp-edit-tags-mode-map' before
+;; calling `define-derived-mode'.)
+(define-key bmkp-edit-tags-mode-map "\C-c\C-c" 'bmkp-edit-tags-send)
+
+;;;###autoload (autoload 'bmkp-edit-tags "bookmark+")
+(defun bmkp-edit-tags (bookmark)        ; Bound to `C-x x t e'
+  "Edit BOOKMARK's tags, and maybe save the result.
+The edited value must be a list each of whose elements is either a
+ string or a cons whose key is a string.
+BOOKMARK is a bookmark name or a bookmark record."
+  (interactive (list (bookmark-completing-read "Edit tags for bookmark" (bmkp-default-bookmark-name))))
+  (setq bookmark  (bmkp-get-bookmark-in-alist bookmark))
+  (let* ((btags    (bmkp-get-tags bookmark))
+         (bmkname  (bmkp-bookmark-name-from-record bookmark))
+         (edbuf    (format "*Edit Tags for Bookmark `%s'*" bmkname)))
+    (setq bmkp-return-buffer  (current-buffer))
+    (bmkp-with-output-to-plain-temp-buffer edbuf
+      (princ
+       (substitute-command-keys
+        (concat ";; Edit tags for bookmark\n;;\n;; \"" bmkname "\"\n;;\n"
+                ";; The edited value must be a list each of whose elements is\n"
+                ";; either a string or a cons whose key is a string.\n;;\n"
+                ";; DO NOT MODIFY THESE COMMENTS.\n;;\n"
+                ";; Type \\<bmkp-edit-tags-mode-map>`\\[bmkp-edit-tags-send]' when done.\n\n")))
+      (let ((print-circle  bmkp-propertize-bookmark-names-flag)
+            (print-gensym  bmkp-propertize-bookmark-names-flag))
+        (pp btags))
+      (goto-char (point-min)))
+    (pop-to-buffer edbuf)
+    (buffer-enable-undo)
+    (with-current-buffer (get-buffer edbuf) (bmkp-edit-tags-mode))))
+
+;;;###autoload (autoload 'bmkp-edit-tags-send "bookmark+")
+(defun bmkp-edit-tags-send (&optional batchp)
+  "Use buffer contents as the internal form of a bookmark's tags.
+DO NOT MODIFY the header comment lines, which begin with `;;'."
+  (interactive)
+  (unless (eq major-mode 'bmkp-edit-tags-mode) (error "Not in `bmkp-edit-tags-mode'"))
+  (let (bname)
+    (unwind-protect
+         (let (tags bmk)
+           (goto-char (point-min))
+           (unless (search-forward ";; Edit tags for bookmark\n;;\n;; ")
+             (error "Missing header in edit buffer"))
+           (unless (stringp (setq bname  (read (current-buffer))))
+             (error "Bad bookmark name in edit-buffer header"))
+           (unless (setq bmk  (bmkp-get-bookmark-in-alist bname 'NOERROR))
+             (error "No such bookmark: `%s'" bname))
+           (goto-char (point-min))
+           (setq tags  (read (current-buffer)))
+           (unless (listp tags) (error "Tags sexp is not a list of strings or an alist with string keys"))
+           (bookmark-prop-set bmk 'tags tags)
+           (setq bname  (bmkp-bookmark-name-from-record bmk))
+           (bmkp-record-visit bmk batchp)
+           (bmkp-refresh/rebuild-menu-list bname batchp)
+           (bmkp-maybe-save-bookmarks)
+           (unless batchp (message "Updated bookmark file with edited tags")))
+      (kill-buffer (current-buffer)))
+    (when bmkp-return-buffer
+      (pop-to-buffer bmkp-return-buffer)
+      (when (equal (buffer-name (current-buffer)) bmkp-bmenu-buffer)
+        (bmkp-bmenu-goto-bookmark-named bname)))))
+
+(defun bmkp-record-visit (bookmark &optional batchp)
+  "Update the data recording a visit to BOOKMARK.
+BOOKMARK is a bookmark name or a bookmark record.
+This increments the `visits' entry and sets the `time' entry to the
+current time.  If either an entry is not present, it is added (with 0
+value for `visits').
+With non-nil optional arg BATCHP, do not rebuild the menu list.
+
+Although this function modifies BOOKMARK, it does not increment
+`bookmark-alist-modification-count', and it does not add BOOKMARK to
+`bmkp-modified-bookmarks'.  This is so that simply recording the visit
+does not count toward needing to save or showing BOOKMARK as modified."
+  (let ((vis                      (bookmark-prop-get bookmark 'visits))
+        (bmkp-modified-bookmarks  bmkp-modified-bookmarks))
+    (bookmark-prop-set bookmark 'visits (if vis (1+ vis) 0))
+    (bookmark-prop-set bookmark 'time   (current-time))
+    (unless batchp (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P))
+    (let ((bookmark-save-flag  nil))  (bmkp-maybe-save-bookmarks 'SAME-COUNT-P))))
+
+(defun bmkp-default-bookmark-name (&optional alist)
+  "Default bookmark name.  See option `bmkp-default-bookmark-name'.
+Non-nil ALIST means return nil unless the default names a bookmark in
+ALIST."
+  (let ((bname  (if (equal (buffer-name (current-buffer)) bmkp-bmenu-buffer)
+                    (bookmark-bmenu-bookmark)
+                  (if (fboundp 'bmkp-default-lighted)
+                      (if (eq 'highlighted bmkp-default-bookmark-name)
+                          (or (bmkp-default-lighted)  bookmark-current-bookmark)
+                        (or bookmark-current-bookmark  (bmkp-default-lighted)))
+                    bookmark-current-bookmark))))
+    (when (consp bname) (setq bname  (car bname))) ; Since `bmkp-default-lighted' can return a list of names.
+    (when (and bname  alist)
+      (setq bname  (bmkp-bookmark-name-from-record (bmkp-bookmark-record-from-name
+                                                    bname 'NOERROR 'MEMP alist))))
+    bname))
+
+(defun bmkp-buffer-names ()
+  "Buffer names used by existing bookmarks that really have buffers.
+This excludes buffers for bookmarks such as desktops that are not
+really associated with a buffer."
+  (let ((bufs  ())
+        buf)
+    (dolist (bmk  bookmark-alist)
+      (when (and (not (bmkp-desktop-bookmark-p        bmk))
+                 (not (bmkp-bookmark-file-bookmark-p  bmk))
+                 (not (bmkp-sequence-bookmark-p       bmk))
+                 (not (bmkp-function-bookmark-p       bmk))
+                 (not (bmkp-variable-list-bookmark-p  bmk))
+                 (setq buf  (bmkp-get-buffer-name     bmk)))
+        (add-to-list 'bufs buf)))
+    bufs))
+
+(defun bmkp-file-names ()
+  "The absolute file names used by the existing bookmarks.
+This excludes the pseudo file name `bmkp-non-file-filename'."
+  (let ((files  ())
+        file)
+    (dolist (bmk  bookmark-alist)
+      (when (and (setq file  (bookmark-get-filename bmk))  (not (equal file bmkp-non-file-filename)))
+        (add-to-list 'files file)))
+    files))
+
+;;;###autoload (autoload 'bmkp-bookmark-set-confirm-overwrite "bookmark+")
+(defun bmkp-bookmark-set-confirm-overwrite (&optional name parg interactivep) ; Bound `C-x r m', `C-x x c m'.
+  "Set a bookmark named NAME, then run `bmkp-after-set-hook'.
+This is the same as `bookmark-set', except that with no prefix arg you
+are asked to confirm overwriting an existing bookmark of the same
+NAME."
+  (interactive (list nil current-prefix-arg t))
+  (let ((bmkp-bookmark-set-confirms-overwrite-p  t))
+    (call-interactively #'bookmark-set)))
+
+;;;###autoload (autoload 'bmkp-send-bug-report "bookmark+")
+(defun bmkp-send-bug-report ()          ; Not bound
+  "Send a bug report about a Bookmark+ problem."
+  (interactive)
+  (browse-url (format (concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\
+Bookmark+ bug: \
+&body=Describe bug below, using a precise recipe that starts with `emacs -Q' or `emacs -q'.  \
+Be sure to mention the `Update #' from header of the particular Bookmark+ file header.\
+%%0A%%0AEmacs version: %s")
+                      (emacs-version))))
+
+;;;###autoload (autoload 'bmkp-toggle-bookmark-set-refreshes "bookmark+")
+(defun bmkp-toggle-bookmark-set-refreshes () ; Not bound
+  "Toggle whether `bookmark-set' refreshes `bookmark-alist' as last filtered.
+Add/remove `bmkp-refresh-latest-bookmark-list' to/from
+`bmkp-after-set-hook'.
+\(Applies also to command `bmkp-bookmark-set-confirm-overwrite'.)"
+  (interactive)
+  (if (member 'bmkp-refresh-latest-bookmark-list bmkp-after-set-hook)
+      (remove-hook 'bmkp-after-set-hook 'bmkp-refresh-latest-bookmark-list)
+    (add-hook 'bmkp-after-set-hook 'bmkp-refresh-latest-bookmark-list)))
+
+(defun bmkp-refresh-latest-bookmark-list ()
+  "Refresh `bmkp-latest-bookmark-alist' to reflect `bookmark-alist'."
+  (setq bmkp-latest-bookmark-alist  (if bmkp-bmenu-filter-function
+                                        (funcall bmkp-bmenu-filter-function)
+                                      bookmark-alist)))
+
+;;;###autoload (autoload 'bmkp-toggle-saving-menu-list-state "bookmark+")
+(defun bmkp-toggle-saving-menu-list-state () ; Bound to `C-M-~' in bookmark list
+  "Toggle the value of option `bmkp-bmenu-state-file'.
+Tip: You can use this before quitting Emacs, to not save the state.
+If the initial value of `bmkp-bmenu-state-file' is nil, then this
+command has no effect."
+  (interactive)
+  (unless (or bmkp-last-bmenu-state-file  bmkp-bmenu-state-file)
+    (error "Cannot toggle: initial value of `bmkp-bmenu-state-file' is nil"))
+  (setq bmkp-last-bmenu-state-file  (prog1 bmkp-bmenu-state-file
+                                      (setq bmkp-bmenu-state-file  bmkp-last-bmenu-state-file)))
+  (message (if bmkp-bmenu-state-file
+               "Autosaving of bookmark list state is now ON"
+             "Autosaving of bookmark list state is now OFF")))
+
+;;;###autoload (autoload 'bmkp-save-menu-list-state "bookmark+")
+(defun bmkp-save-menu-list-state (&optional msg-p) ; Used in `bookmark-exit-hook-internal'.
+  "Save menu-list state, unless not saving or list has not yet been shown.
+The state is saved to the value of `bmkp-bmenu-state-file'.
+Non-interactively, optional arg MSG-P means display progress messages."
+  (interactive "p")
+  (when (and (not bmkp-bmenu-first-time-p)  bmkp-bmenu-state-file)
+    (when msg-p (message "Saving bookmark-list display state..."))
+    (let ((config-list
+           `((last-sort-comparer                    . ,bmkp-sort-comparer)
+             (last-reverse-sort-p                   . ,bmkp-reverse-sort-p)
+             (last-reverse-multi-sort-p             . ,bmkp-reverse-multi-sort-p)
+             (last-latest-bookmark-alist            . ,(bmkp-maybe-unpropertize-bookmark-names
+                                                        bmkp-latest-bookmark-alist))
+             (last-bmenu-omitted-bookmarks          . ,(bmkp-maybe-unpropertize-bookmark-names
+                                                        bmkp-bmenu-omitted-bookmarks 'COPY))
+             (last-bmenu-marked-bookmarks           . ,(bmkp-maybe-unpropertize-bookmark-names
+                                                        bmkp-bmenu-marked-bookmarks 'COPY))
+             (last-bmenu-filter-function            . ,bmkp-bmenu-filter-function)
+             (last-bmenu-filter-pattern             . ,bmkp-bmenu-filter-pattern)
+             (last-bmenu-title                      . ,bmkp-bmenu-title)
+             (last-bmenu-bookmark                   . ,(and (get-buffer bmkp-bmenu-buffer)
+                                                            (with-current-buffer
+                                                                (get-buffer bmkp-bmenu-buffer)
+                                                              (bmkp-maybe-unpropertize-string
+                                                               (bookmark-bmenu-bookmark) 'COPY))))
+             ;; Use `copy-sequence' here just in case, to avoid circular references when
+             ;; `bmkp-propertize-bookmark-names-flag' is nil.
+             (last-specific-buffer                  . ,(copy-sequence bmkp-last-specific-buffer))
+             (last-specific-file                    . ,(copy-sequence bmkp-last-specific-file))
+             (last-bmenu-toggle-filenames           . ,bookmark-bmenu-toggle-filenames)
+             (last-bmenu-before-hide-marked-alist   . ,(bmkp-maybe-unpropertize-bookmark-names
+                                                        bmkp-bmenu-before-hide-marked-alist 'COPY))
+             (last-bmenu-before-hide-unmarked-alist . ,(bmkp-maybe-unpropertize-bookmark-names
+                                                        bmkp-bmenu-before-hide-unmarked-alist 'COPY))
+             (last-bookmark-file                    . ,(copy-sequence
+                                                        (convert-standard-filename
+                                                         (expand-file-name
+                                                          bmkp-current-bookmark-file))))
+             (last-previous-bookmark-file           . ,(and bmkp-last-bookmark-file
+                                                            (copy-sequence
+                                                             (convert-standard-filename
+                                                              (expand-file-name
+                                                               bmkp-last-bookmark-file))))))))
+      (with-current-buffer (let ((enable-local-variables  ())) (find-file-noselect bmkp-bmenu-state-file))
+        (goto-char (point-min))
+        (delete-region (point-min) (point-max))
+        (let ((print-length           nil)
+              (print-level            nil)
+              (print-circle           bmkp-propertize-bookmark-names-flag)
+              (print-gensym           bmkp-propertize-bookmark-names-flag)
+              (version-control        (case bookmark-version-control
+                                        ((nil)      nil)
+                                        (never      'never)
+                                        (nospecial  version-control)
+                                        (t          t)))
+              (require-final-newline  t)
+              (errorp                 nil))
+          (pp config-list (current-buffer))
+          (condition-case nil
+              (write-file bmkp-bmenu-state-file)
+            (file-error
+             (setq errorp  t)
+             ;; Do NOT raise error - used in `bookmark-exit-hook-internal'.  (Need to be able to exit.)
+             (let ((msg  (format "CANNOT WRITE FILE `%s'" bmkp-bmenu-state-file)))
+               (if (fboundp 'display-warning)
+                   (display-warning 'bookmark-plus msg)
+                 (message msg)
+                 (sit-for 4)))))
+          (kill-buffer (current-buffer))
+          (when (and msg-p  (not errorp)) (message "Saving bookmark-list display state...done")))))))
+
+;;;###autoload (autoload 'bmkp-toggle-saving-bookmark-file "bookmark+")
+(defun bmkp-toggle-saving-bookmark-file (&optional msg-p) ; Bound to `M-~' in bookmark list
+  "Toggle the value of option `bookmark-save-flag'.
+If the initial value of `bookmark-save-flag' is nil, then this
+command has no effect.
+Non-interactively, non-nil MSG-P means display a status message."
+  (interactive "p")
+  (unless (or bmkp-last-save-flag-value  bookmark-save-flag)
+    (error "Cannot toggle: initial value of `bookmark-save-flag' is nil"))
+  ;; One of the two vars should be nil.  If both are non-nil, set `*-last-*' to nil before toggling.
+  (when (and bmkp-last-save-flag-value  bookmark-save-flag) (setq bmkp-last-save-flag-value  nil))  
+  (setq bmkp-last-save-flag-value  (prog1 bookmark-save-flag
+                                     (setq bookmark-save-flag  bmkp-last-save-flag-value)))
+  (when msg-p (message (if bookmark-save-flag
+                           "Autosaving of current bookmark file is now ON"
+                         "Autosaving of current bookmark file is now OFF"))))
+
+;; Same as `read-from-whole-string' (called `thingatpt--read-from-whole-string' starting with Emacs 25)
+;; in library `thingatpt.el'.
+;;
+(defun bmkp-read-from-whole-string (string)
+  "Read a Lisp expression from STRING.
+Raise an error if the entire string was not used."
+  (let* ((read-data  (read-from-string string))
+         (more-left (condition-case nil
+                        ;; The call to `ignore' suppresses a compiler warning.
+                        (progn (ignore (read-from-string (substring string (cdr read-data))))
+                               t)
+                      (end-of-file nil))))
+    (if more-left (error "Can't read whole string") (car read-data))))
+
+;;;###autoload (autoload 'bmkp-jump-to-list "bookmark+")
+(defun bmkp-jump-to-list (bookmark
+                          &optional position msgp) ; Bound globally to `C-x j C-j', `C-x x C-j'
+  "Jump to BOOKMARK entry in `*Bookmark List*'.
+You are prompted for BOOKMARK (a bookmark name).
+If you use library `bookmark+-lit.el':
+ * The defaults for BOOKMARK are the lighted bookmarks at point.
+ * A prefix arg means only lighted bookmarks at point are candidates."
+  (interactive (let* ((litp   (fboundp 'bmkp-bookmarks-lighted-at-point))
+                      (lbmks  (and litp  (bmkp-bookmarks-lighted-at-point (point) nil 'MSG)))
+                      (bmk    (bookmark-completing-read (if current-prefix-arg "Lighted bookmark" "Bookmark")
+                                                        (and litp  (if current-prefix-arg (car lbmks) lbmks))
+                                                        (and current-prefix-arg  lbmks))))
+                 (list bmk (point) t)))
+  (pop-to-buffer (get-buffer-create bmkp-bmenu-buffer))
+  (bookmark-bmenu-list)
+  (bmkp-bmenu-goto-bookmark-named (setq bmkp-last-bmenu-bookmark  bookmark)))
+
+;;;###autoload (autoload 'bmkp-make-function-bookmark "bookmark+")
+(defun bmkp-make-function-bookmark (bookmark-name function &optional msg-p) ; Bound globally to `C-x x c F'.
+  "Create a bookmark that invokes FUNCTION when \"jumped\" to.
+You are prompted for the bookmark name and the name of the function.
+But with a prefix arg the last keyboard macro defined is used instead
+of prompting you for a function.
+
+Returns the new bookmark (internal record).
+
+Non-interactively, non-nil optional arg MSG-P means display a status
+message."
+  (interactive (let ((icicle-unpropertize-completion-result-flag  t))
+                 (list (bmkp-completing-read-lax "Bookmark")
+                       (if (and current-prefix-arg  last-kbd-macro)
+                           (read-kbd-macro last-kbd-macro 'NEED-VECTOR)
+                         (completing-read "Function: " obarray 'functionp))
+                       'MSG)))
+  (unless (or (functionp function)  (vectorp function))
+    (setq function (bmkp-read-from-whole-string function))) ; Convert name to symbol.
+  (bookmark-store bookmark-name `(,@(bookmark-make-record-default 'NO-FILE 'NO-CONTEXT 0 nil 'NO-REGION)
+                                  (function . ,function)
+                                  (handler  . bmkp-jump-function))
+                  nil nil (not msg-p))
+  (let ((new  (bmkp-bookmark-record-from-name bookmark-name 'NOERROR)))
+    (unless (memq new bmkp-latest-bookmark-alist)
+      (setq bmkp-latest-bookmark-alist  (cons new bmkp-latest-bookmark-alist)))
+    (bookmark-bmenu-surreptitiously-rebuild-list (not msg-p))
+    new))
+
+;;;###autoload (autoload 'bmkp-set-dired-bookmark-for-files "bookmark+")
+(defun bmkp-set-dired-bookmark-for-files (bookmark-name dired-name to-add &optional switches msg-p)
+  "Create a Dired bookmark for a set of files and directories.
+You are prompted for the Dired buffer name and the file or directory
+entries to include.  With a prefix arg, you are also prompted for the
+`ls' switches.
+
+Use `C-g' when done choosing file and directory names.  Any directory
+names you choose this way are included as single entries in the
+listing - the directory contents are not included.  To instead include
+the contents of a directory, use a glob pattern: put `/*' after the
+directory name.
+
+You need library `Dired+' for this command."
+  (interactive
+   (let* ((_IGNORE             (unless (require 'dired+ nil t)
+                                 (error "You need library `Dired+' for this command")))
+          (current-prefix-arg  (if current-prefix-arg 0 -1))
+          (all                 (diredp-dired-union-interactive-spec
+                                "add files/dirs "
+                                'NO-DIRED-BUFS
+                                'READ-EXTRA-FILES-P)))
+     (list (bmkp-completing-read-lax "Bookmark") (nth 0 all) (nth 3 all) (nth 2 all) 'MSG)))
+  (bmkp-make-function-bookmark
+   bookmark-name
+   `(lambda () (diredp-add-to-dired-buffer ',dired-name ',to-add ',switches))
+   msg-p))
+
+(when (boundp 'grep-history)            ; Emacs 26+
+  (defun bmkp-set-grep-command-bookmark (bookmark-name &optional grep-cmd msg-p)
+    "Create a bookmark to run the last grep command.
+With a prefix arg, you are prompted for the grep command to record,
+ with lax completion against your previous `grep' inputs in this
+ session."
+    (interactive
+     (let ((parg  current-prefix-arg))
+       (unless grep-history (error "Emacs command `grep' has not yet been run"))
+       (list (bmkp-completing-read-lax "Bookmark")
+             (and parg
+                  (completing-read "Grep command: "
+                                   grep-history nil t nil 'grep-history (car grep-history)))
+             'MSG)))
+    (setq grep-cmd  (or grep-cmd  (car grep-history)))
+    (unless (stringp grep-cmd) (error "Emacs command `grep' has not yet been run"))
+    (bmkp-make-function-bookmark bookmark-name
+                                 `(lambda () (funcall #'grep ,grep-cmd))
+                                 msg-p)))
+
+;;;###autoload (autoload 'bmkp-revert-bookmark-file "bookmark+")
+(defun bmkp-revert-bookmark-file (&optional msg-p) ; Same as `C-u g' in bookmark list (but not bound).
+  "Revert to the bookmarks in the current bookmark file.
+You are asked for confirmation.
+
+This DISCARDS all modifications to bookmarks and the bookmark list
+\(e.g. added/deleted bookmarks) since the last bookmark-file save.
+IOW, it reloads the bookmark file, overwriting the current bookmark
+list.  This also removes any markings and omissions.
+
+This has the same effect as using `C-u \\<bookmark-bmenu-mode-map>\\[bmkp-bmenu-refresh-menu-list]' in \
+buffer `*Bookmark List*'.
+To refresh the display from the current bookmark list instead of the
+bookmark file, use just `\\[bmkp-bmenu-refresh-menu-list]' (no `C-u').
+
+Non-interactively, non-nil MSG-P means display a status message."
+  (interactive "p")
+  (when (and msg-p  (not (yes-or-no-p (format "Revert to bookmarks saved in file `%s'? "
+                                              bmkp-current-bookmark-file))))
+    (error "OK - canceled"))
+  (bookmark-load bmkp-current-bookmark-file 'OVERWRITE msg-p) ; Do not let `bookmark-load' ask to save.
+  (bmkp-refresh/rebuild-menu-list nil (not msg-p)))
+
+;;;###autoload (autoload 'bmkp-switch-bookmark-file "bookmark+")
+(defun bmkp-switch-bookmark-file (file &optional batchp) ; Not bound and not used in the code now.
+  "Switch to a different bookmark file, FILE.
+Return FILE.  Interactively, you are prompted for FILE.
+Replace all bookmarks in the current bookmark list with those from the
+newly loaded FILE.  Bookmarks are subsequently saved to FILE.
+
+Optional arg BATCHP is passed to `bookmark-load'."
+  (interactive
+   (list  (let* ((std-default  (bmkp-default-bookmark-file))
+                 (default      (if (bmkp-same-file-p bmkp-current-bookmark-file bmkp-last-bookmark-file)
+                                   (if (bmkp-same-file-p bmkp-current-bookmark-file std-default)
+                                       bookmark-default-file
+                                     std-default)
+                                 bmkp-last-bookmark-file)))
+            (bmkp-read-bookmark-file-name "Switch to bookmark file: "
+                                          (or (file-name-directory default)  "~/")
+                                          default
+                                          t)))) ; Require that the file exist.
+  (bookmark-load file t batchp))        ; Treat it interactively, if this command is called interactively.
+
+;;;###autoload (autoload 'bmkp-switch-to-last-bookmark-file "bookmark+")
+(defun bmkp-switch-to-last-bookmark-file (&optional batchp) ; Not bound to key, but effectively `C-u C-x x L'
+  "Switch back to the last-used bookmark file.
+Replace all currently existing bookmarks with those newly loaded from
+the last-used file.  Swap the values of `bmkp-last-bookmark-file' and
+`bmkp-current-bookmark-file'.
+
+Optional arg BATCHP is passed to `bookmark-load'."
+  (interactive)
+  (bookmark-load (or bmkp-last-bookmark-file  (bmkp-default-bookmark-file))
+                 t batchp))             ; Treat it interactively, if this command is called interactively.
+
+;;;###autoload (autoload 'bmkp-switch-bookmark-file-create "bookmark+")
+(defun bmkp-switch-bookmark-file-create (file &optional switch-to-lastp batchp)
+                                        ; Bound to `C-x x L', (`L' in bookmark list)
+  "Switch to bookmark file FILE, creating it as empty if it does not exist.
+With a prefix arg, switch to the last bookmark file used.
+Otherwise, you are prompted for FILE.
+
+Replace all bookmarks in the current bookmark list with those from the
+newly loaded file.  Bookmarks are subsequently saved to that file.
+
+If there is no file with the name you provide (FILE), then create a
+new, empty bookmark file with that name and use that from now on.
+This empties the bookmark list.  Interactively, you are required to
+confirm this.
+
+Return the newly current bookmark file.
+
+When called from Lisp:
+* FILE is the bookmark-file name or nil (meaning use the last one).
+* Non-nil BATCHP is passed to `bookmark-load'."
+  (interactive
+   (if current-prefix-arg
+       (list nil current-prefix-arg)
+     (list (let* ((std-default  (bmkp-default-bookmark-file))
+                  (default      (if (bmkp-same-file-p bmkp-current-bookmark-file bmkp-last-bookmark-file)
+                                    (if (bmkp-same-file-p bmkp-current-bookmark-file std-default)
+                                        bookmark-default-file
+                                      std-default)
+                                  bmkp-last-bookmark-file)))
+             (bmkp-read-bookmark-file-name "Switch to bookmark file: "
+                                           (or (file-name-directory default)  "~/")
+                                           default))
+           nil)))
+  (if (not switch-to-lastp)
+      (let ((empty-p  nil))
+        (if (file-readable-p file)
+;;;     (if (or batchp  (y-or-n-p (format "CONFIRM: `%s' as the current bookmark file? " file)))
+;;;         (bookmark-load file t batchp)
+;;;       (error "OK, canceled"))
+            (bookmark-load file t batchp) ; Treat it interactively, if this command is called interactively.
+          (setq empty-p  t)
+          (when (and (not batchp)
+                     (not (y-or-n-p (format "Create and use NEW, EMPTY bookmark file `%s'? " file))))
+            (error "OK - canceled"))
+          (bmkp-empty-file file)
+          (bookmark-load file t batchp)) ; Treat it interactively, if this command is called interactively.
+        (unless batchp (message "Bookmark file is now %s`%s'" (if empty-p "EMPTY file " "") file)))
+    (bmkp-switch-to-last-bookmark-file batchp)
+    (setq file  bmkp-current-bookmark-file))
+  file)
+
+;;;###autoload (autoload 'bmkp-switch-to-bookmark-file-this-file/buffer "bookmark+")
+(defun bmkp-switch-to-bookmark-file-this-file/buffer (file &optional batchp) ; Bound to `C-x x C-l'
+  "Switch to a bookmark file for bookmarks in this file or buffer.
+If visiting a file, the bookmarks are â€˜bmkp-this-file-alist-only’.
+Otherwise, they are â€˜bmkp-this-buffer-alist-only’.
+
+If there are unsaved bookmarks in the current bookmark list you are
+first prompted to save it.
+
+You are then prompted for the bookmark file to switch to, for
+bookmarks only for this file/buffer."
+  (interactive
+   (list (let* ((std-default  (bmkp-default-bookmark-file))
+                (default      (if (bmkp-same-file-p bmkp-current-bookmark-file bmkp-last-bookmark-file)
+                                  (if (bmkp-same-file-p bmkp-current-bookmark-file std-default)
+                                      bookmark-default-file
+                                    std-default)
+                                bmkp-last-bookmark-file)))
+           (bmkp-read-bookmark-file-name "Switch to bookmark file for bookmarks here: "
+                                         (or (and default  (file-name-directory default))  "~/")
+                                         default))))
+  (bmkp-switch-bookmark-file-create file))
+
+(defun bmkp-read-bookmark-file-name (&optional prompt dir default-filename require-match)
+  "Read and return an (absolute) bookmark file name.
+PROMPT is the prompt to use (default: \"Use bookmark file: \").
+The other args are the same as for `read-file-name'."
+  (let ((insert-default-directory                    t)
+        (icicle-unpropertize-completion-result-flag  t)) ; For `read-file-name'.
+    (expand-file-name
+     (read-file-name (or prompt  "Use bookmark file: ") dir default-filename require-match))))
+
+(defun bmkp-read-bookmark-file-default ()
+  "A default value for `bmkp-read-bookmark-file-name' DEFAULT-FILENAME arg.
+A value to use if you want a default and there is none better."
+  (if (and (> emacs-major-version 22)
+           (not (bmkp-same-file-p "~/.emacs.bmk" bookmark-default-file)))
+      (list "~/.emacs.bmk" bookmark-default-file)
+    "~/.emacs.bmk"))
+
+;;;###autoload (autoload 'bmkp-empty-file "bookmark+")
+(defun bmkp-empty-file (file &optional confirmp) ; Bound to `C-x x 0'
+  "Empty the bookmark file FILE, or create FILE (empty) if it does not exist.
+In either case, FILE will become an empty bookmark file.  Return FILE.
+
+NOTE: If FILE already exists and you confirm emptying it, no check is
+      made that it is in fact a bookmark file before emptying it.
+      It is simply replaced by an empty bookmark file and saved.
+
+This does NOT also make FILE the current bookmark file.  To do that,
+use `\\[bmkp-switch-bookmark-file-create]' (`bmkp-switch-bookmark-file-create').
+
+Interactively, and non-interactively if optional arg CONFIRMP is
+non-nil, require confirmation if the file already exists."
+  (interactive (list (let ((icicle-unpropertize-completion-result-flag  t))
+                       (read-file-name "Create empty bookmark file: " "~/"))
+                     t))
+  (setq file  (expand-file-name file))
+  (when (file-directory-p file) (error "`%s' is a directory, not a file" file))
+  (bookmark-maybe-load-default-file)
+  (when (and confirmp  (file-exists-p file)
+             (not (y-or-n-p (format "CONFIRM: Empty the existing file `%s'? " file))))
+    (error "OK - canceled"))
+  (let ((bookmark-alist  ()))
+    (bookmark-write-file file nil (if (file-exists-p file)
+                                      "Emptying bookmark file `%s'..."
+                                    "Creating new, empty bookmark file `%s'...")))
+  file)
+
+(defun bmkp-write-alist-bookmarks-to-file (alist file &optional addp)
+  "Write bookmarks in ALIST to FILE.
+By default, replace FILE with only the ALIST bookmarks.
+Non-nil ADDP means just add the bookmarks to those already in
+FILE (updating them if already present)."
+  (when (file-directory-p file) (error "`%s' is a directory, not a file" file))
+  (let ((bookmark-save-flag                 nil) ; Inhibit auto-saving for the duration.
+        (bookmark-alist                     bookmark-alist)
+        (bookmark-alist-modification-count  bookmark-alist-modification-count)
+        imported)
+    (with-current-buffer (let ((enable-local-variables  ())) (find-file-noselect file))
+      (goto-char (point-min))
+      (if (file-exists-p file)
+          (bookmark-maybe-upgrade-file-format)
+        (delete-region (point-min) (point-max)) ; In case a find-file hook inserted a header etc.
+        (if (boundp 'bookmark-file-coding-system) ; Insert timestamp and an empty bookmark list.
+            (bookmark-insert-file-format-version-stamp bookmark-file-coding-system) ; Emacs 25.2+
+          (bookmark-insert-file-format-version-stamp))
+        (insert "(\n)"))
+      (let ((blist  (bookmark-alist-from-buffer)))
+        (unless (listp blist) (error "Invalid bookmark list in file `%s'" file))
+        (setq bookmark-alist  blist)    ; Bookmarks in FILE
+        (setq imported  (bookmark-import-new-list alist nil 'RETURN-BMKS))
+        (unless (and (zerop (nth 0 imported))  (zerop (nth 1 imported)))
+          (bookmark-write-file file))))))
+
+;;;###autoload (autoload 'bmkp-save-bookmarks-this-file/buffer "bookmark+")
+(defun bmkp-save-bookmarks-this-file/buffer (file &optional addp batchp) ; Bound to `C-x x C-s'
+  "Save bookmarks defined for the current file/buffer to FILE.
+If visiting a file, the bookmarks are â€˜bmkp-this-file-alist-only’.
+Otherwise, they are â€˜bmkp-this-buffer-alist-only’.
+
+You are prompted for FILE, the bookmark file to save to.
+
+By default, replace FILE with only the bookmarks for the current
+file/buffer.  With a prefix arg, just add the bookmarks to those
+already in FILE (updating them if already present).
+
+This does NOT make FILE the current bookmark file.  To do that, use
+`bmkp-switch-to-bookmark-file-this-file/buffer'."
+  (interactive
+   (list (let* ((std-default  (bmkp-default-bookmark-file))
+                (default      (if (bmkp-same-file-p bmkp-current-bookmark-file bmkp-last-bookmark-file)
+                                   (if (bmkp-same-file-p bmkp-current-bookmark-file std-default)
+                                       bookmark-default-file
+                                     std-default)
+                                 bmkp-last-bookmark-file)))
+           (bmkp-read-bookmark-file-name "File to save bookmarks in: "
+                                         (or (and default  (file-name-directory default))  "~/")
+                                         default))
+         current-prefix-arg))
+  (when (file-directory-p file) (error "`%s' is a directory, not a file" file))
+  (when (and (not (file-readable-p file))
+             (not batchp)
+             (not (y-or-n-p (format "Save to NEW, EMPTY bookmark file `%s'? " file))))
+    (error "OK - canceled"))
+  (bmkp-write-alist-bookmarks-to-file (bmkp-this-file/buffer-alist-only) file addp))
+
+;;;###autoload (autoload 'bmkp-crosshairs-highlight "bookmark+")
+(defun bmkp-crosshairs-highlight ()     ; Not bound
+  "Highlight point with crosshairs temporarily.
+Do not highlight if either the region is active or
+`bmkp-crosshairs-flag' is nil.
+
+You can add this to hook `bookmark-after-jump-hook'.
+You need library `crosshairs.el' to use this command."
+  (interactive)
+  (when (and bmkp-crosshairs-flag  (> emacs-major-version 21)) ; No-op for Emacs 20-21.
+    (unless (condition-case nil (require 'crosshairs nil t) (error nil))
+      (error "You need library `crosshairs.el' to use this command"))
+    (unless mark-active
+      (let ((crosshairs-overlay-priority  (and (boundp 'bmkp-light-priorities)
+                                               (1+ (apply #'max
+                                                          (mapcar #'cdr bmkp-light-priorities))))))
+        (crosshairs-highlight)))))
+
+;;;###autoload (autoload 'bmkp-choose-navlist-from-bookmark-list "bookmark+")
+(defun bmkp-choose-navlist-from-bookmark-list (bookmark &optional alist) ; Bound to `C-x x B'
+  "Choose a bookmark-list bookmark and set the bookmark navigation list.
+The navigation-list variable, `bmkp-nav-alist', is set to the list of
+bookmarks that would be displayed by `bookmark-bmenu-list' (`C-x r l')
+for the chosen bookmark-list bookmark, sorted and filtered as
+appropriate.
+
+Instead of choosing a bookmark-list bookmark, you can choose the
+pseudo-bookmark `CURRENT *Bookmark List*'.  The bookmarks used for the
+navigation list are those that would be currently shown in the
+`*Bookmark List*' (even if the list is not currently displayed).
+
+BOOKMARK is a bookmark name or a bookmark record.
+Optional arg ALIST is an alternative alist of bookmarks to use."
+  (interactive
+   (let ((bookmark-alist  (cons (bmkp-current-bookmark-list-state) (bmkp-bookmark-list-alist-only))))
+     (list (bmkp-read-bookmark-for-type "bookmark-list" bookmark-alist nil nil
+                                        'bmkp-bookmark-list-history "Choose ")
+           bookmark-alist)))
+  (setq alist  (or alist  (cons (bmkp-current-bookmark-list-state) (bmkp-bookmark-list-alist-only))))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR alist)))
+  (let ((state  (let ((bookmark-alist  alist)) (bookmark-prop-get bookmark 'bookmark-list))))
+    (let ((bname                            (bmkp-bookmark-name-from-record bookmark))
+          (bmkp-sort-comparer               (cdr (assq 'last-sort-comparer              state)))
+          (bmkp-reverse-sort-p              (cdr (assq 'last-reverse-sort-p             state)))
+          (bmkp-reverse-multi-sort-p        (cdr (assq 'last-reverse-multi-sort-p       state)))
+          (bmkp-bmenu-omitted-bookmarks     (cdr (assq 'last-bmenu-omitted-bookmarks    state)))
+          (bmkp-bmenu-filter-function       (cdr (assq 'last-bmenu-filter-function      state)))
+          (bmkp-bmenu-filter-pattern        (or (cdr (assq 'last-bmenu-filter-pattern   state))  ""))
+          (bmkp-bmenu-title                 (cdr (assq 'last-bmenu-title                state)))
+          (bookmark-bmenu-toggle-filenames  (cdr (assq 'last-bmenu-toggle-filenames     state))))
+      (setq bmkp-nav-alist             (bmkp-sort-omit
+                                        (if bmkp-bmenu-filter-function
+                                            (funcall bmkp-bmenu-filter-function)
+                                          (if (string= "CURRENT *Bookmark List*" bname)
+                                              (or bmkp-latest-bookmark-alist  bookmark-alist)
+                                            bookmark-alist))
+                                        (and (not (eq bmkp-bmenu-filter-function
+                                                      'bmkp-omitted-alist-only))
+                                             bmkp-bmenu-omitted-bookmarks))
+            bmkp-current-nav-bookmark  (car bmkp-nav-alist))
+      (message "Bookmark navigation list is now %s"
+               (if (and (string= "CURRENT *Bookmark List*" bname)  (not (get-buffer bmkp-bmenu-buffer)))
+                   "the global bookmark list"
+                 (format "`%s'" bname))))))
+
+(defun bmkp-current-bookmark-list-state ()
+  "Pseudo-bookmark for the current `*Bookmark List*' state."
+  (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P)
+  (cons "CURRENT *Bookmark List*" (bmkp-make-bookmark-list-record)))
+
+;;; This function is used in macro `bmkp-define-history-variables', so
+;;; its definition is also in `bookmark+-mac.el'.
+;;;
+(defun bmkp-types-alist ()
+  "Alist of bookmark types used by `bmkp-jump-to-type'.
+Keys are bookmark type names.  Values are corresponding history variables.
+The alist is used in commands such as `bmkp-jump-to-type'."
+  (let ((entries  ()))
+    (mapatoms
+     (lambda (sym)
+       (let ((name  (symbol-name sym)))
+         (when (string-match "\\`bmkp-\\(.+\\)-alist-only\\'" name)
+           (push (cons (match-string 1 name)
+                       (intern (format "bmkp-%s-history" (match-string 1 name))))
+                 entries)))))
+    entries))
+
+;;;###autoload (autoload 'bmkp-choose-navlist-of-type "bookmark+")
+(defun bmkp-choose-navlist-of-type (type) ; Bound to `C-x x :'
+  "Set the bookmark navigation list to the bookmarks of a type you choose.
+The pseudo-type `any' sets the navigation list to all bookmarks.
+This sets variable `bmkp-nav-alist'."
+  (interactive
+   (let* ((completion-ignore-case                      t)
+          (icicle-unpropertize-completion-result-flag  t)
+          (type                                        (completing-read "Type: "
+                                                                        (cons '("any" . bookmark-history)
+                                                                              (bmkp-types-alist))
+                                                                        nil t nil nil "any")))
+     (list type)))
+  (setq bmkp-nav-alist  (if (equal "any" type)
+                            bookmark-alist
+                          (funcall (intern (format "bmkp-%s-alist-only" type)))))
+  (unless bmkp-nav-alist (error "No bookmarks"))
+  (setq bmkp-current-nav-bookmark  (car bmkp-nav-alist))
+  (message "Bookmark navigation list is now %s"
+           (if (equal "any" type) "all bookmarks" (format "for type `%s'" type))))
+
+(defun bmkp-autonamed-bookmark-p (bookmark &optional buffer)
+  "Return non-nil if BOOKMARK is an autonamed bookmark for BUFFER.
+If BUFFER is nil then any buffer is OK.
+BOOKMARK is a bookmark name or a bookmark record.
+BUFFER, if non-nil, is a buffer or a buffer name."
+  (unless (stringp bookmark) (setq bookmark  (bmkp-bookmark-name-from-record bookmark)))
+  (when (bufferp buffer) (setq buffer  (buffer-name buffer)))
+  (let ((nargs  0)
+        (start  0))
+    (save-match-data
+      (while (string-match "%\\([+ #-0]+\\)?\\([0-9]+\\)?\\([.][0-9]+\\)?[BsSdoxXefgc]"
+                           bmkp-autoname-format
+                           start)
+        (setq nargs  (1+ nargs)
+              start  (match-end 0))))
+    (bmkp-string-match-p
+     (apply #'format
+            (bmkp-format-spec bmkp-autoname-format `((?B . ,(if buffer (regexp-quote buffer) ".*"))))
+            (make-list nargs ".*"))
+     bookmark)))
+
+(defun bmkp-format-spec (format specification)
+  "Like `format-spec', but respect standard `format' %-sequences.
+%-sequences specified in SPECIFICATION are handled per `format-spec'
+Any standard `format' %-sequences not specified in SPECIFICATION are
+left as is.
+
+This is also more general than `format-spec', in that the full format
+of a %-sequence is supported: `%<flags><width><precision>character'.
+`format-spec' does not support precision>, and it supports only the
+flags `-' and `0'."
+  (with-temp-buffer
+    (insert format)
+    (goto-char (point-min))
+    (while (search-forward "%" nil t)
+      (cond ((eq (char-after) ?%) (delete-char 1)) ; Quoted percent sign.
+            ((looking-at "\\([+ #-0]+\\)?\\([0-9]+\\)?\\([.][0-9]+\\)?\\([a-zA-Z]\\)")
+             (let* ((num   (match-string 2))
+                    (spec  (string-to-char (match-string 4)))
+                    (val   (assq spec specification)))
+               (if (not val)
+                   ;; Ignore standard format chars that are not redefined by SPECIFICATION.
+                   (unless (memq (string-to-char (match-string 4)) '(?s ?S ?d ?o ?x ?X ?e ?f ?g ?c))
+                     (error "Invalid format character: `%%%c'" spec))
+                 (setq val  (cdr val))
+                 (let ((text  (format (concat "%" num "s") val))) ; Pad result to desired length.
+                   (insert-and-inherit text) ; Insert first, to preserve text properties.
+                   (delete-region (+ (match-beginning 0) (length text)) ; Delete specifier body.
+                                  (+ (match-end 0) (length text)))
+                   (delete-region (1- (match-beginning 0)) ; Delete percent sign.
+                                  (match-beginning 0))))))
+            (t (error "Invalid format string"))))
+    (buffer-string)))
+
+(defun bmkp-autonamed-this-buffer-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is an autonamed bookmark for this buffer."
+  (unless (stringp bookmark) (setq bookmark  (bmkp-bookmark-name-from-record bookmark)))
+  (bmkp-autonamed-bookmark-p bookmark (buffer-name)))
+
+(defun bmkp-autonamed-bookmark-for-buffer-p (bookmark buffer-name)
+  "Return non-nil if BOOKMARK is an autonamed bookmark for BUFFER.
+BOOKMARK is a bookmark name or a bookmark record.
+BUFFER-NAME is a string matching the buffer-name part of an autoname.
+This does not check the `buffer-name' entry of BOOKMARK.  It checks
+only the buffer indicated by the bookmark name."
+  (unless (stringp bookmark) (setq bookmark  (bmkp-bookmark-name-from-record bookmark)))
+  (bmkp-autonamed-bookmark-p bookmark buffer-name))
+
+(defun bmkp-update-autonamed-bookmark (bookmark)
+  "Update the name and position of the autonamed BOOKMARK at point.
+Return the updated BOOKMARK: If input was a bookmark name, then return
+ then new name, else the new (full) bookmark.
+It is a good idea to set BOOKMARK to the result of this call.
+BOOKMARK is a bookmark name or a bookmark record."
+  (let ((namep  (stringp bookmark)))
+    (setq bookmark  (bmkp-get-bookmark bookmark))
+    (bookmark-set-position bookmark (point))
+    ;; Autonamed bookmarks do not have regions.  Update `end-position' to be the same as `position'.
+    (when (bmkp-get-end-position bookmark)
+      (bookmark-prop-set bookmark 'end-position (point)))
+    (let ((newname  (funcall bmkp-autoname-bookmark-function (point))))
+      (bookmark-rename (bmkp-bookmark-name-from-record bookmark) newname 'BATCHP)
+      (bmkp-refresh/rebuild-menu-list (bmkp-bookmark-name-from-record bookmark)) ; So display new name.
+      (bmkp-maybe-save-bookmarks))
+    (if namep (bmkp-bookmark-name-from-record bookmark) bookmark))) ; Return updated bookmark or name.
+
+;;;###autoload (autoload 'bmkp-this-file/buffer-bmenu-list "bookmark+")
+(defun bmkp-this-file/buffer-bmenu-list () ; Bound to `C-x x ,'
+  "Show the bookmark list just for bookmarks for the current file/buffer.
+If visiting a file, this is `bmkp-this-file-bmenu-list'.  Otherwise,
+this is `bmkp-this-buffer-bmenu-list'."
+  (interactive)
+  (if (buffer-file-name) (bmkp-this-file-bmenu-list) (bmkp-this-buffer-bmenu-list)))
+
+;;;###autoload (autoload 'bmkp-this-file-bmenu-list "bookmark+")
+(defun bmkp-this-file-bmenu-list ()
+  "Show the bookmark list just for bookmarks for the current file.
+Set `bmkp-last-specific-file' to the current file name.
+If the current buffer is not visiting a file, prompt for the file name."
+  (interactive)
+  (unless bookmark-alist (bookmark-maybe-load-default-file)) ; Just to be sure.
+  (let ((orig-last-spec-file  bmkp-last-specific-file)
+        (orig-filter-fn       bmkp-bmenu-filter-function)
+        (orig-title           bmkp-bmenu-title)
+        (orig-latest-alist    bmkp-latest-bookmark-alist))
+    (condition-case err
+        (progn
+          (setq bmkp-last-specific-file     (or (buffer-file-name)
+                                                (let ((icicle-unpropertize-completion-result-flag  t))
+                                                  (read-file-name "File: ")))
+                bmkp-bmenu-filter-function  'bmkp-last-specific-file-alist-only
+                bmkp-bmenu-title            (format "File `%s' Bookmarks" bmkp-last-specific-file))
+          (let ((bookmark-alist         (funcall bmkp-bmenu-filter-function))
+                (bmkp-bmenu-state-file  nil)) ; Prevent restoring saved state.
+            (unless bookmark-alist (error "No bookmarks for file `%s'" bmkp-last-specific-file))
+            (setq bmkp-latest-bookmark-alist  bookmark-alist)
+            (pop-to-buffer (get-buffer-create bmkp-bmenu-buffer))
+            (bookmark-bmenu-list 'filteredp))
+          (when (interactive-p)
+            (bmkp-msg-about-sort-order (bmkp-current-sort-order)
+                                       (format "Only bookmarks for file `%s' are shown"
+                                               bmkp-last-specific-file)))
+          (raise-frame))
+      (error (progn (setq bmkp-last-specific-file     orig-last-spec-file
+                          bmkp-bmenu-filter-function  orig-filter-fn
+                          bmkp-bmenu-title            orig-title
+                          bmkp-latest-bookmark-alist  orig-latest-alist)
+                    (error "%s" (error-message-string err)))))))
+
+;;;###autoload (autoload 'bmkp-this-buffer-bmenu-list "bookmark+")
+(defun bmkp-this-buffer-bmenu-list ()
+  "Show the bookmark list just for bookmarks for the current buffer.
+Set `bmkp-last-specific-buffer' to the current buffer name."
+  (interactive)
+  (unless bookmark-alist (bookmark-maybe-load-default-file))
+  (let ((orig-last-spec-buf  bmkp-last-specific-buffer)
+        (orig-filter-fn      bmkp-bmenu-filter-function)
+        (orig-title          bmkp-bmenu-title)
+        (orig-latest-alist   bmkp-latest-bookmark-alist))
+    (condition-case err
+        (progn
+          (setq bmkp-last-specific-buffer   (buffer-name)
+                bmkp-bmenu-filter-function  'bmkp-last-specific-buffer-alist-only
+                bmkp-bmenu-title            (format "Buffer `%s' Bookmarks"
+                                                    bmkp-last-specific-buffer))
+          (let ((bookmark-alist         (funcall bmkp-bmenu-filter-function))
+                (bmkp-bmenu-state-file  nil)) ; Prevent restoring saved state.
+            (unless bookmark-alist (error "No bookmarks for buffer `%s'"
+                                          bmkp-last-specific-buffer))
+            (setq bmkp-latest-bookmark-alist  bookmark-alist)
+            (pop-to-buffer (get-buffer-create bmkp-bmenu-buffer))
+            (bookmark-bmenu-list 'filteredp))
+          (when (interactive-p)
+            (bmkp-msg-about-sort-order (bmkp-current-sort-order)
+                                       (format "Only bookmarks for buffer `%s' are shown"
+                                               bmkp-last-specific-buffer)))
+          (raise-frame))
+      (error (progn (setq bmkp-last-specific-buffer   orig-last-spec-buf
+                          bmkp-bmenu-filter-function  orig-filter-fn
+                          bmkp-bmenu-title            orig-title
+                          bmkp-latest-bookmark-alist  orig-latest-alist)
+                    (error "%s" (error-message-string err)))))))
+
+;;;###autoload (autoload 'bmkp-navlist-bmenu-list "bookmark+")
+(defun bmkp-navlist-bmenu-list ()       ; Bound to `C-x x N'
+  "Show the bookmark list just for bookmarks from the navigation list."
+  (interactive)
+  (unless bmkp-nav-alist
+    (bookmark-maybe-load-default-file)
+    (setq bmkp-nav-alist  bookmark-alist)
+    (unless bmkp-nav-alist (error "No bookmarks"))
+    (setq bmkp-current-nav-bookmark  (car bmkp-nav-alist))
+    (message "Bookmark navigation list is now the GLOBAL bookmark list") (sit-for 2))
+  (let ((orig-title         bmkp-bmenu-title)
+        (orig-latest-alist  bmkp-latest-bookmark-alist))
+    (condition-case err
+        (progn
+          (setq bmkp-bmenu-title  "Current Navlist Bookmarks")
+          (let ((bookmark-alist         bmkp-nav-alist)
+                (bmkp-bmenu-state-file  nil)) ; Prevent restoring saved state.
+            (unless bookmark-alist (error "No bookmarks"))
+            (setq bmkp-latest-bookmark-alist  bookmark-alist)
+            (pop-to-buffer (get-buffer-create bmkp-bmenu-buffer))
+            (bookmark-bmenu-list 'filteredp))
+          (when (interactive-p)
+            (bmkp-msg-about-sort-order (bmkp-current-sort-order)
+                                       "Only bookmarks for the navigation list are shown"))
+          (raise-frame))
+      (error (progn (setq bmkp-bmenu-title            orig-title
+                          bmkp-latest-bookmark-alist  orig-latest-alist)
+                    (error "%s" (error-message-string err)))))))
+
+(defun bmkp-completing-read-buffer-name (&optional no-default-p)
+  "Read the name of a buffer associated with a bookmark.
+The candidates are the buffers in `bmkp-buffer-names'.
+Non-nil NO-DEFAULT-P means provide no default value.  Used when
+ called in a loop, to let the user exit using empty input.
+If NO-DEFAULT-P is nil, then the default is the current buffer's name,
+ or the value of `bmkp-last-specific-buffer' if the current buffer has
+ no bookmarks."
+  (bookmark-maybe-load-default-file)
+  (let ((icicle-unpropertize-completion-result-flag  t))
+    (completing-read "Buffer: " (mapcar #'list (bmkp-buffer-names)) nil t nil 'buffer-name-history
+                     (and (not no-default-p)
+                          (if (member (buffer-name) (bmkp-buffer-names))
+                              (buffer-name)
+                            bmkp-last-specific-buffer)))))
+
+(defun bmkp-completing-read-file-name (&optional no-default-p)
+  "Read the name of a file associated with a bookmark.
+The candidates are the absolute file names in `bmkp-file-names'.
+Non-nil NO-DEFAULT-P means provide no default value.  Used when
+ called in a loop, to let the user exit using empty input.
+If NO-DEFAULT-P is nil, then the default is the current buffer's file
+ name, if any, or the value of `bmkp-last-specific-file' if the
+ current buffer has no associated file or the file has no bookmarks."
+  (bookmark-maybe-load-default-file)
+  (let ((completion-ignore-case                      (if (boundp 'read-file-name-completion-ignore-case)
+                                                         read-file-name-completion-ignore-case
+                                                       (memq system-type
+                                                             '(ms-dos windows-nt darwin cygwin))))
+        (icicle-unpropertize-completion-result-flag  t))
+    (completing-read "File: " (mapcar #'list (bmkp-file-names)) nil t nil 'file-name-history
+                     (and (not no-default-p)
+                          (let ((file  (buffer-file-name)))
+                            (if (and file  (member file (bmkp-file-names)))
+                                file
+                              bmkp-last-specific-file))))))
+
+(defun bmkp-refresh/rebuild-menu-list (&optional bookmark no-msg-p)
+  "Refresh or rebuild buffer `*Bookmark List*'.
+If the buffer is already displayed, call `bmkp-refresh-menu-list'.
+Otherwise, call `bookmark-bmenu-surreptitiously-rebuild-list'.
+Args are the same as for `bmkp-refresh-menu-list'."
+  (let ((bmklistbuf  (get-buffer bmkp-bmenu-buffer)))
+    (if (and bmklistbuf  (get-buffer-window bmklistbuf 0))
+        (with-current-buffer bmklistbuf (bmkp-refresh-menu-list bookmark no-msg-p))
+      (bookmark-bmenu-surreptitiously-rebuild-list no-msg-p))))
+
+(defun bmkp-refresh-menu-list (&optional bookmark no-msg-p)
+  "Refresh (revert) the bookmark list (\"menu list\").
+This brings the displayed list up to date.  It does not change the
+current filtering or sorting of the displayed list.
+Non-nil optional arg BOOKMARK means move cursor to BOOKMARK's line.
+BOOKMARK is a bookmark name or a bookmark record.
+Non-nil optional arg NO-MSG-P means do not show progress messages."
+  (let ((bookmark-alist  (if bmkp-bmenu-filter-function
+                             (funcall bmkp-bmenu-filter-function)
+                           bookmark-alist)))
+    (setq bmkp-latest-bookmark-alist  bookmark-alist)
+    (unless no-msg-p  (message "Updating bookmark list..."))
+    (bookmark-bmenu-list bmkp-bmenu-filter-function) ; No filter function means start anew.
+    (when bookmark
+      (unless (stringp bookmark) (setq bookmark  (bmkp-bookmark-name-from-record bookmark)))
+      (with-current-buffer (get-buffer bmkp-bmenu-buffer)
+        (bmkp-bmenu-goto-bookmark-named bookmark)
+        (let ((bmenu-win  (get-buffer-window (current-buffer) 0)))
+          (when bmenu-win (set-window-point bmenu-win (point))))))
+    (unless no-msg-p  (message "Updating bookmark list...done"))))
+
+;;;###autoload (autoload 'bmkp-unomit-all "bookmark+")
+(defun bmkp-unomit-all (&optional msg-p) ; Bound to `O U' in bookmark list
+  "Remove all bookmarks from the list of omitted bookmarks.
+After this, all bookmarks are available for display.
+Non-interactively, non-nil optional arg MSG-P means display a status
+message."
+  (interactive "p")
+  (unless bmkp-bmenu-omitted-bookmarks (error "No omitted bookmarks to UN-omit"))
+  (when msg-p (message "UN-omitting ALL omitted bookmarks..."))
+  (let ((count  0))
+    (dolist (bmk-name  bmkp-bmenu-omitted-bookmarks)
+      (setq bmkp-bmenu-omitted-bookmarks  (bmkp-delete-bookmark-name-from-list
+                                           bmk-name bmkp-bmenu-omitted-bookmarks)
+            count                         (1+ count)))
+    (bookmark-bmenu-surreptitiously-rebuild-list (not msg-p))
+    (when msg-p (message "UN-omitted %d bookmarks" count)))
+  (when (equal (buffer-name (current-buffer)) bmkp-bmenu-buffer) (bmkp-bmenu-show-all))
+  (when (and (fboundp 'fit-frame-if-one-window)  (equal (buffer-name (current-buffer)) bmkp-bmenu-buffer))
+    (fit-frame-if-one-window)))
+
+
+;;(@* "Search-and-Replace Locations of Marked Bookmarks")
+;;  *** Search-and-Replace Locations of Marked Bookmarks ***
+
+(when (> emacs-major-version 22)
+  (defvar bmkp-isearch-bookmarks nil
+    "Bookmarks whose locations are to be incrementally searched.")
+
+  (defun bmkp-isearch-next-bookmark-buffer (&optional bookmark wrap)
+    "Return the next buffer in a series of bookmark buffers.
+Used as a value for `multi-isearch-next-buffer-function', for Isearch
+of multiple bookmarks.
+
+Variable `bmkp-isearch-bookmarks' is a list of bookmarks.  Each
+bookmark in the list is visited by `bookmark--jump-via', and the
+corresponding bookmark buffer is returned."
+    (let ((bookmarks  (if isearch-forward bmkp-isearch-bookmarks (reverse bmkp-isearch-bookmarks))))
+      (bookmark--jump-via
+       (if wrap
+           (car bookmarks)
+         (let ((this-bmk  (catch 'bmkp-isearch-next-bookmark-buffer
+                            (dolist (bmk  bookmarks)
+                              (when (if (bmkp-get-buffer-name bmk)
+                                        (equal (bmkp-get-buffer-name bmk) (buffer-name))
+                                      (equal (bookmark-get-filename bmk) (buffer-file-name)))
+                                (throw 'bmkp-isearch-next-bookmark-buffer bmk)))
+                            (car bookmarks))))
+           (cadr (member this-bmk bookmarks))))
+       'ignore)
+      (current-buffer)))
+
+  (defun bmkp-isearch-bookmarks (bookmarks)
+    "Start multi-bookmark Isearch on BOOKMARKS."
+    (let ((multi-isearch-next-buffer-function  'bmkp-isearch-next-bookmark-buffer)
+          (bmkp-isearch-bookmarks              bookmarks))
+      (bookmark-jump (car bookmarks))
+      (goto-char (if isearch-forward (point-min) (point-max)))
+      (isearch-forward)))
+
+  (defun bmkp-isearch-bookmarks-regexp (bookmarks)
+    "Start multi-bookmark regexp Isearch on BOOKMARKS."
+    (let ((multi-isearch-next-buffer-function  'bmkp-isearch-next-bookmark-buffer)
+          (bmkp-isearch-bookmarks              bookmarks))
+      (bookmark-jump (car bookmarks))
+      (goto-char (if isearch-forward (point-min) (point-max)))
+      (isearch-forward-regexp))))
+
+
+;;(@* "Tags")
+;;  *** Tags ***
+
+(defun bmkp-get-tags (bookmark)
+  "Return the `tags' entry for BOOKMARK.
+BOOKMARK is a bookmark name or a bookmark record."
+  (bookmark-prop-get bookmark 'tags))
+
+(defalias 'bmkp-tagged-bookmark-p 'bmkp-get-tags)
+
+(defun bmkp-get-tag-value (bookmark tag)
+  "Return value of BOOKMARK's tag TAG.
+BOOKMARK is a bookmark name or a bookmark record.
+TAG is a string.
+Return nil if BOOKMARK has no such TAG or if TAG has no value."
+  (assoc-default tag (bmkp-get-tags bookmark)))
+
+(defun bmkp-has-tag-p (bookmark tag)
+  "Return non-nil if BOOKMARK is tagged with TAG.
+BOOKMARK is a bookmark name or a bookmark record.
+TAG is a string."
+  (assoc-default tag (bmkp-get-tags bookmark) nil t))
+
+;; NOT USED currently - we use `bmkp-read-tags-completing' instead.
+(defun bmkp-read-tags ()
+  "Read tags one by one, and return them as a list."
+  (let ((tag    (read-string "Tag (RET for each, empty input to finish): "))
+        (btags  ()))
+    (while (not (string= "" tag))
+      (push tag btags)
+      (setq tag  (read-string "Tag: ")))
+    btags))
+
+(defun bmkp-read-tag-completing (&optional prompt candidate-tags require-match update-tags-alist-p)
+  "Read a tag with completion, and return it as a string.
+The candidate tags available are determined by option
+`bmkp-tags-for-completion'.
+
+PROMPT is the prompt string.  If nil, then use \"Tag: \".
+CANDIDATE-TAGS is an alist of tags to use for completion.
+ If nil, then all tags from all bookmarks are used for completion.
+ The set of all tags is taken from variable `bmkp-tags-alist'.
+REQUIRE-MATCH is passed to `completing-read'.
+Non-nil UPDATE-TAGS-ALIST-P means update var `bmkp-tags-alist'."
+  (bookmark-maybe-load-default-file)
+  (let ((cand-tags                                   (copy-sequence
+                                                      (or candidate-tags
+                                                          (and (not update-tags-alist-p)
+                                                               bmkp-tags-alist) ; Use cached list.
+                                                          (bmkp-tags-list)))) ; Update the cache.
+        (icicle-unpropertize-completion-result-flag  t))
+    (completing-read (or prompt  "Tag: ") cand-tags nil require-match nil 'bmkp-tag-history)))
+
+(defun bmkp-read-tags-completing (&optional candidate-tags require-match update-tags-alist-p)
+  "Read tags with completion, and return them as a list of strings.
+Read tags one by one, until you hit `RET' twice consecutively.
+
+CANDIDATE-TAGS is an alist of tags to use for completion.
+ If nil then the candidate tags are taken from variable
+ `bmkp-tags-alist'.
+REQUIRE-MATCH is passed to `completing-read'.
+Non-nil UPDATE-TAGS-ALIST-P means update var `bmkp-tags-alist',
+determining the tags to use per option `bmkp-tags-for-completion'."
+  (bookmark-maybe-load-default-file)
+  (let ((cands                                       ())
+        (btags                                       ())
+        (prompt1                                     "Tag (RET for each, empty input to finish): ")
+        (prompt2                                     "Tag: ")
+        (icicle-unpropertize-completion-result-flag  t)
+        tag old-tag)
+    ;; Make a new candidates alist, with just one entry per tag name.  The original cdr is discarded.
+    (dolist (full-tag  (or candidate-tags
+                           (and (not update-tags-alist-p)  bmkp-tags-alist) ; Use cached list.
+                           (bmkp-tags-list)))
+      (add-to-list 'cands (list (if (consp full-tag) (car full-tag) full-tag))))
+    (setq tag    (completing-read prompt1 cands nil require-match nil 'bmkp-tag-history)
+          cands  (delete (assoc tag cands) cands)) ; Tag read is no longer a candidate.
+    (while (not (string= "" tag))
+      (if (member tag btags)            ; User can enter it more than once, if not REQUIRE-MATCH.
+          (message "Tag `%s' already included" tag)
+        (push tag btags))               ; But we only add it once.
+      (setq tag    (completing-read prompt2 cands nil require-match nil 'bmkp-tag-history)
+            cands  (delete (assoc tag cands) cands)))
+    (nreverse btags)))
+
+;;;###autoload (autoload 'bmkp-list-all-tags "bookmark+")
+(defun bmkp-list-all-tags (fullp current-only-p &optional msg-p)
+                                        ; Bound to `C-x x t l', (`T l' in bookmark list)
+  "List bookmark tags.
+Show the list in the minibuffer or, if not enough space, in buffer
+`*All Tags*'.  The tags are listed alphabetically, respecting option
+`case-fold-search'.
+
+With no prefix arg or with a plain prefix arg (`C-u'), the tags listed
+are those defined by option `bmkp-tags-for-completion'.  Otherwise
+\(i.e., with a numeric prefix arg), the tags listed are those from the
+current list of bookmarks only.
+
+With no prefix arg or with a negative prefix arg (e.g. `C--'), list
+only the tag names.  With a non-negative prefix arg (e.g. `C-1' or
+plain `C-u'), list the full alist of tags.
+
+Note that when the full tags alist is shown, the same tag name appears
+once for each of its different values.
+
+Non-interactively, non-nil MSG-P means display a status message."
+  (interactive (list (and current-prefix-arg  (> (prefix-numeric-value current-prefix-arg) 0))
+                     (and current-prefix-arg  (not (consp current-prefix-arg)))
+                     'MSG))
+  (require 'pp)
+  (when msg-p (message "Gathering tags..."))
+  (pp-display-expression  (sort (bmkp-tags-list (not fullp) current-only-p)
+                                (if fullp
+                                    (lambda (t1 t2) (bmkp-string-less-case-fold-p (car t1) (car t2)))
+                                  'bmkp-string-less-case-fold-p))
+                          "*All Tags*"))
+
+(defun bmkp-tags-list (&optional names-only-p current-only-p)
+  "List of all bookmark tags, per option `bmkp-tags-for-completion'.
+Non-nil NAMES-ONLY-P means return a list of only the tag names.
+Otherwise, return an alist of the full tags and set variable
+`bmkp-tags-alist' to that alist, as a cache.
+
+Non-nil CURRENT-ONLY-P means ignore option `bmkp-tags-for-completion'
+and return only the tags for the currently loaded bookmarks."
+  (let ((tags      ())
+        (opt-tags  bmkp-tags-for-completion)
+        bmk-tags)
+    (when (or (eq opt-tags 'current)  current-only-p)  (setq opt-tags '(current)))
+    (dolist (entry  opt-tags)
+      (typecase entry
+        (cons                           ; A bookmark file
+         (when (eq 'bmkfile (car entry))
+           (setq entry  (cdr entry)
+                 tags   (append tags (bmkp-tags-in-bookmark-file entry names-only-p)))))
+        (string (add-to-list 'tags (if names-only-p entry (list entry))))
+        (symbol (when (eq entry 'current)
+                  (bookmark-maybe-load-default-file)
+                  (dolist (bmk  bookmark-alist)
+                    (setq bmk-tags  (bmkp-get-tags bmk))
+                    (dolist (tag  bmk-tags)
+                      (add-to-list 'tags (if names-only-p (bmkp-tag-name tag) (bmkp-full-tag tag)))))))))
+    (unless names-only-p (setq bmkp-tags-alist  tags))
+    tags))
+
+(defun bmkp-tags-in-bookmark-file (file &optional names-only-p)
+  "Return the list of tags from all bookmarks in bookmark-file FILE.
+If FILE is a relative file name, it is expanded in `default-directory.
+If FILE does not name a valid, bookmark file then nil is returned.
+Non-nil NAMES-ONLY-P means return a list of only the tag names.
+Otherwise, return an alist of the full tags."
+  (setq file  (expand-file-name file))
+  (when (file-directory-p file) (error "`%s' is a directory, not a file" file))
+  (let ((bookmark-save-flag  nil)       ; Just to play safe.
+        (bmk-alist           ())
+        (tags                ())
+        bmk-tags)
+    (if (not (file-readable-p file))
+        (message "Cannot read bookmark file `%s'" file)
+      (with-current-buffer (let ((enable-local-variables  ())) (find-file-noselect file))
+        (goto-char (point-min))
+        (condition-case nil             ; Check whether it's a valid bookmark file.
+            (progn (bookmark-maybe-upgrade-file-format)
+                   (unless (listp (setq bmk-alist  (bookmark-alist-from-buffer))) (error "")))
+          (error (message "Not a valid bookmark file: `%s'" file))))
+      (dolist (bmk  bmk-alist)
+        (setq bmk-tags  (bmkp-get-tags bmk))
+        (dolist (tag  bmk-tags)
+          (add-to-list 'tags (if names-only-p (bmkp-tag-name tag) (bmkp-full-tag tag))))))
+    tags))
+
+(defun bmkp-tag-name (tag)
+  "Name of TAG.  If TAG is an atom, then TAG, else (car TAG)."
+  (if (atom tag) tag (car tag)))
+
+(defun bmkp-full-tag (tag)
+  "Full cons entry for TAG.  If TAG is a cons, then TAG, else (list TAG)."
+  (if (consp tag) tag (list tag)))
+
+;;;###autoload (autoload 'bmkp-remove-all-tags "bookmark+")
+(defun bmkp-remove-all-tags (bookmark &optional no-update-p msg-p)
+                                        ; Bound to `C-x x t 0', (`T 0' in bookmark list)
+  "Remove all tags from BOOKMARK.
+Non-interactively:
+ - Non-nil NO-UPDATE-P means do not update `bmkp-tags-alist', do not
+   update the modification count and maybe save bookmarks, and do not
+   refresh/rebuild the bookmark-list display
+ - Non-nil optional arg MSG-P means show a message about the removal."
+  (interactive (list (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name)) nil 'MSG))
+  (when (and msg-p  (null (bmkp-get-tags bookmark)))  (error "Bookmark has no tags to remove"))
+  (let ((nb-removed  (and (interactive-p)  (length (bmkp-get-tags bookmark)))))
+    (bookmark-prop-set bookmark 'tags ())
+    (unless no-update-p
+      (bmkp-tags-list)                  ; Update the tags cache.
+      (bmkp-maybe-save-bookmarks)       ; Increments `bookmark-alist-modification-count'.
+      (bmkp-refresh/rebuild-menu-list bookmark (not msg-p))) ; So remove `t' marker and add `*' marker.
+    (when (and msg-p  nb-removed)  (message "%d tags removed" nb-removed)))) ; Do after msg from refreshing.
+
+
+;;;###autoload (autoload 'bmkp-add-tags "bookmark+")
+(defun bmkp-add-tags (bookmark tags &optional no-update-p msg-p)
+                                        ; `C-x x t + b' (`b' for bookmark), (`T +' in bookmark list)
+  "Add TAGS to BOOKMARK.
+Hit `RET' to enter each tag, then hit `RET' again after the last tag.
+You can use completion to enter the bookmark name and each tag.
+Completion for the bookmark name is strict.
+Completion for tags is lax: you are not limited to existing tags.
+
+By default, the tag choices for completion are NOT refreshed, to save
+time.  Use a prefix argument if you want to refresh them.
+
+Non-interactively:
+ - TAGS is a list of strings.
+ - Non-nil MSG-P means display a message about the addition.
+ - Non-nil NO-UPDATE-P means do not update `bmkp-tags-alist', do not
+   update the modification count and maybe save bookmarks, and do not
+   refresh/rebuild the bookmark-list display
+
+The absolute value of the return value is the number of tags added.
+If BOOKMARK was untagged before the operation, then the return value
+is negative."
+  (interactive (list (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name))
+                     (bmkp-read-tags-completing nil nil current-prefix-arg)
+                     nil
+                     'MSG))
+  (let* ((newtags  (copy-alist (bmkp-get-tags bookmark)))
+         (olen     (length newtags)))
+    (dolist (tag  tags)  (unless (or (assoc tag newtags)  (member tag newtags))  (push tag newtags)))
+    (bookmark-prop-set bookmark 'tags newtags)
+    (unless no-update-p
+      (bmkp-tags-list) ; Update the tags cache.
+      (bmkp-maybe-save-bookmarks)  ; Increments `bookmark-alist-modification-count'.
+      (bmkp-refresh/rebuild-menu-list bookmark (not msg-p))) ; So display `t' and `*' markers for BOOKMARK.
+    (let ((nb-added  (- (length newtags) olen)))
+      (when msg-p (message "%d tags added. Now: %S" nb-added ; Echo just the tag names.
+                           (let ((tgs  (mapcar #'bmkp-tag-name newtags))) (setq tgs (sort tgs #'string<)))))
+      (when (and (zerop olen)  (> (length newtags) 0)) (setq nb-added  (- nb-added)))
+      nb-added)))
+
+;; $$$$$$ Not yet used
+;;;###autoload (autoload 'bmkp-set-tag-value-for-navlist "bookmark+")
+(defun bmkp-set-tag-value-for-navlist (tag value &optional msg-p) ; Bound to `C-x x t V'
+  "Set the value of TAG to VALUE, for each bookmark in the navlist.
+If any of the bookmarks has no tag named TAG, then add one with VALUE."
+  (interactive (list (bmkp-read-tag-completing) (read (read-string "Value: ")) 'msg))
+  (bmkp-set-tag-value-for-bookmarks bmkp-nav-alist tag value msg-p))
+
+;; $$$$$$ Not yet used
+(defun bmkp-set-tag-value-for-bookmarks (bookmarks tag value &optional msg-p) ; Not bound
+  "Set the value of TAG to VALUE, for each of the BOOKMARKS.
+If any of the BOOKMARKS has no tag named TAG, then add one with VALUE."
+  (let ((bookmark-save-flag  (and (not bmkp-count-multi-mods-as-one-flag)
+                                  bookmark-save-flag))) ; Save only after `dolist'.
+    (dolist (bmk  bookmarks) (bmkp-set-tag-value bmk tag value 'NO-UPDATE-P)))
+  (bmkp-tags-list)                      ; Update the tags cache.
+  (bmkp-maybe-save-bookmarks)           ; Increments `bookmark-alist-modification-count'.
+  (bmkp-refresh/rebuild-menu-list nil (not msg-p)))
+
+;;;###autoload (autoload 'bmkp-set-tag-value "bookmark+")
+(defun bmkp-set-tag-value (bookmark tag value &optional no-update-p msg-p) ; Bound to `C-x x t v'
+  "For BOOKMARK's TAG, set the value to VALUE.
+If BOOKMARK has no tag named TAG, then add one with value VALUE.
+Non-interactively:
+ - Non-nil NO-UPDATE-P means do not update `bmkp-tags-alist', do not
+   update the modification count and maybe save bookmarks, and do not
+   refresh/rebuild the bookmark-list display
+ - Non-nil MSG-P means display a message about the updated value."
+  (interactive
+   (let* ((bmk  (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name)))
+          (tag  (bmkp-read-tag-completing "Tag: " (mapcar 'bmkp-full-tag (bmkp-get-tags bmk)))))
+     (list bmk tag (read (read-string "Value: ")) nil 'MSG)))
+  (unless (bmkp-has-tag-p bookmark tag) (bmkp-add-tags bookmark (list tag) 'NO-UPDATE-P)) ; No update yet.
+  (let* ((newtags     (copy-alist (bmkp-get-tags bookmark)))
+         (assoc-tag   (assoc tag newtags))
+         (member-tag  (and (not assoc-tag)  (member tag newtags))))
+    (if assoc-tag (setcdr assoc-tag value) (setcar member-tag (cons (car member-tag) value)))
+    (bookmark-prop-set bookmark 'tags newtags))
+  (unless no-update-p
+    (bmkp-tags-list)                    ; Update the tags cache.
+    (bmkp-maybe-save-bookmarks)         ; Increments `bookmark-alist-modification-count'.
+    (bmkp-refresh/rebuild-menu-list bookmark (not msg-p))) ; So display `t' and `*' markers for BOOKMARK.
+  (when msg-p "Tag value set"))
+
+;;;###autoload (autoload 'bmkp-remove-tags "bookmark+")
+(defun bmkp-remove-tags (bookmark tags &optional no-update-p msg-p)
+                                        ; `C-x x t - b' (`b' for bookmark), (`T -' in bookmark list)
+  "Remove TAGS from BOOKMARK.
+Hit `RET' to enter each tag, then hit `RET' again after the last tag.
+You can use completion to enter the bookmark name and each tag.
+
+By default, the tag choices for completion are NOT refreshed, to save
+time.  Use a prefix argument if you want to refresh them.
+
+Non-interactively:
+ - TAGS is a list of strings.  The corresponding tags are removed.
+ - Non-nil MSG-P means display status messages.
+ - Non-nil NO-UPDATE-P means do not update `bmkp-tags-alist', do not
+   update the modification count and maybe save bookmarks, and do not
+   refresh/rebuild the bookmark-list display
+
+The absolute value of the return value is the number of tags removed.
+If BOOKMARK is untagged after the operation, then the return value
+is negative."
+  (interactive (let ((bmk  (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name))))
+                 (list bmk
+                       (bmkp-read-tags-completing (mapcar 'bmkp-full-tag (bmkp-get-tags bmk))
+                                                  t current-prefix-arg)
+                       nil
+                       'MSG)))
+  (let* ((remtags  (copy-alist (bmkp-get-tags bookmark)))
+         (olen     (length remtags)))
+    (if (null remtags)
+        (when msg-p (message "Bookmark has no tags to remove")) ; Do nothing if bookmark has no tags.
+      (setq remtags  (bmkp-remove-if (lexical-let ((tgs  tags))
+                                       (lambda (tag)
+                                         (if (atom tag) (member tag tgs) (member (car tag) tgs))))
+                                     remtags))
+      (bookmark-prop-set bookmark 'tags remtags)
+      (unless no-update-p
+        (bmkp-tags-list)                ; Update the tags cache.
+        (bmkp-maybe-save-bookmarks)     ; Increments `bookmark-alist-modification-count'.
+        (bmkp-refresh/rebuild-menu-list bookmark (not msg-p))) ; So remove `t' marker if no tags.
+      (let ((nb-removed  (- olen (length remtags))))
+        (when msg-p (message "%d tags removed. Now: %S" nb-removed ; Echo just the tag names.
+                             (let ((tgs  (mapcar #'bmkp-tag-name remtags)))
+                               (setq tgs (sort tgs #'string<)))))
+        (when (and (zerop (length remtags))  (> olen 0)) (setq nb-removed  (- nb-removed)))
+        nb-removed))))
+
+;;;###autoload (autoload 'bmkp-remove-tags-from-all "bookmark+")
+(defun bmkp-remove-tags-from-all (tags &optional msg-p) ; Bound to `C-x x t d', (`T d' in bookmark list)
+  "Remove TAGS from all bookmarks.
+Hit `RET' to enter each tag, then hit `RET' again after the last tag.
+You can use completion to enter each tag.
+This affects all bookmarks, even those not showing in bookmark list.
+
+By default, the tag choices for completion are NOT refreshed, to save
+time.  Use a prefix argument if you want to refresh them.
+
+Non-interactively:
+* TAGS is a list of strings.  The corresponding tags are removed.
+* Non-nil optional arg MSG-P means show a message about the deletion."
+  (interactive
+   (if (not (y-or-n-p "Delete the tags you specify from ALL bookmarks? "))
+       (error "OK - deletion canceled")
+     (list (bmkp-read-tags-completing nil t current-prefix-arg) 'MSG)))
+  (let ((bookmark-save-flag  (and (not bmkp-count-multi-mods-as-one-flag)
+                                  bookmark-save-flag))) ; Save only after `dolist'.
+    (dolist (bmk  (bookmark-all-names)) (bmkp-remove-tags bmk tags 'NO-UPDATE-P)))
+  (bmkp-tags-list)                      ; Update the tags cache (only once, at end).
+  (bmkp-maybe-save-bookmarks)           ; Increments `bookmark-alist-modification-count'.
+  (bmkp-refresh/rebuild-menu-list nil (not msg-p)) ; So remove `t' markers when no tags anymore.
+  (when msg-p (message "Tags removed from all bookmarks: %S" tags)))
+
+;;;###autoload (autoload 'bmkp-rename-tag "bookmark+")
+(defun bmkp-rename-tag (tag newname &optional msg-p) ; Bound to `C-x x t r', (`T r' in bookmark list)
+  "Rename TAG to NEWNAME in all bookmarks, even those not showing.
+Non-interactively, non-nil MSG-P means display a message about the
+deletion."
+  (interactive (list (bmkp-read-tag-completing "Tag (old name): ")
+                     (bmkp-read-tag-completing "New name: ")
+                     'MSG))
+  (let ((tag-exists-p        nil)
+        (bookmark-save-flag  (and (not bmkp-count-multi-mods-as-one-flag)
+                                  bookmark-save-flag))) ; Save only after `dolist'.
+    (dolist (bmk  (bookmark-all-names))
+      (let ((newtags  (copy-alist (bmkp-get-tags bmk))))
+        (when newtags
+          (let* ((assoc-tag   (assoc tag newtags))
+                 (member-tag  (and (not assoc-tag)  (member tag newtags))))
+            (cond (assoc-tag  (setcar assoc-tag newname))
+                  (member-tag (setcar member-tag newname)))
+            (when (or assoc-tag  member-tag)
+              (setq tag-exists-p  t)
+              (bookmark-prop-set bmk 'tags newtags))))))
+    (unless tag-exists-p (error "No such tag: `%s'" tag)))
+  (bmkp-tags-list)                      ; Update the tags cache now, after iterating.
+  (bmkp-maybe-save-bookmarks)           ; Increments `bookmark-alist-modification-count'.
+  ;; (bmkp-refresh/rebuild-menu-list nil (not msg-p)) ; $$$$$$ No need to redisplay
+  (when msg-p (message "Renamed")))
+
+;;;###autoload (autoload 'bmkp-copy-tags "bookmark+")
+(defun bmkp-copy-tags (bookmark &optional msg-p) ; Bound to `C-x x t c', `C-x x t M-w'
+  "Copy tags from BOOKMARK, so you can paste them to another bookmark.
+Note that you can copy from a BOOKMARK that has no tags or has an
+empty tags list.  In that case, the copied-tags list is empty, so if
+you paste it as a replacement then the recipient bookmark will end up
+with no tags.
+
+Non-interactively, non-nil MSG-P means display a message about the
+number of tags copied."
+  (interactive (list (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name)) 'MSG))
+  (let ((btags  (bmkp-get-tags bookmark)))
+    (setq bmkp-copied-tags  (copy-alist btags))
+    (when msg-p (message "%d tags now available for pasting" (length btags)))))
+
+;;;###autoload (autoload 'bmkp-paste-add-tags "bookmark+")
+(defun bmkp-paste-add-tags (bookmark &optional no-update-p msg-p) ; Bound to `C-x x t p', `C-x x t C-y'
+  "Add tags to BOOKMARK that were previously copied from another bookmark.
+Return the number of tags added.
+The tags are copied from `bmkp-copied-tags'.
+Non-interactively:
+ - Non-nil NO-UPDATE-P means do not update `bmkp-tags-alist', do not
+   update the modification count and maybe save bookmarks, and do not
+   refresh/rebuild the bookmark-list display
+ - Non-nil MSG-P means display a message about the addition."
+  (interactive (list (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name)) nil 'MSG))
+  (unless (listp bmkp-copied-tags) (error "`bmkp-paste-add-tags': `bmkp-copied-tags' is not a list"))
+  (bmkp-add-tags bookmark bmkp-copied-tags no-update-p msg-p))
+
+;;;###autoload (autoload 'bmkp-paste-replace-tags "bookmark+")
+(defun bmkp-paste-replace-tags (bookmark &optional no-update-p msg-p) ; Bound to `C-x x t q'
+  "Replace tags for BOOKMARK with those copied from another bookmark.
+Return the number of tags for BOOKMARK.
+The tags are copied from `bmkp-copied-tags'.
+Any previously existing tags for BOOKMARK are *lost*.
+
+NOTE: It is by design that you can *remove all* tags from a bookmark
+by copying an empty set of tags and then pasting to that bookmark
+using this command.  So be careful using it.  If you want to be sure
+that you do not replace tags with an empty list of tags, you can check
+the value of variable `bmkp-copied-tags' before pasting.
+
+Non-interactively:
+ - Non-nil NO-UPDATE-P means do not update `bmkp-tags-alist', do not
+   update the modification count and maybe save bookmarks, and do not
+   refresh/rebuild the bookmark-list display
+ - Non-nil MSG-P means display a message about the addition."
+  (interactive (list (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name)) nil 'MSG))
+  (unless (listp bmkp-copied-tags)
+    (error "`bmkp-paste-replace-tags': `bmkp-copied-tags' is not a list"))
+  (let ((has-tags-p  (bmkp-get-tags bookmark)))
+    (when (and msg-p  has-tags-p
+               (not (y-or-n-p "Existing tags will be LOST - really replace them? ")))
+      (error "OK - paste-replace tags canceled"))
+    (when has-tags-p (bmkp-remove-all-tags bookmark no-update-p msg-p) (sleep-for 0.5)))
+  (bmkp-add-tags bookmark bmkp-copied-tags no-update-p msg-p))
+
+
+;;(@* "Bookmark Predicates")
+;;  *** Bookmark Predicates ***
+
+(defun bmkp-annotated-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK has an annotation.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (setq bookmark  (bmkp-get-bookmark bookmark))
+  (let ((annotation  (bookmark-get-annotation bookmark)))
+    (and annotation  (not (string-equal annotation "")))))
+
+(defun bmkp-autofile-bookmark-p (bookmark &optional prefix)
+  "Return non-nil if BOOKMARK is an autofile bookmark.
+That means both:
+ * It is `bmkp-file-bookmark-p'.
+ * Its bookmark name is the same as the nondirectory part of its file
+   name (or of its `directory-file-name', if a directory).
+
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'.
+
+Non-interactively, non-nil optional arg PREFIX means that the bookmark
+name is actually expected to be the file name prefixed by PREFIX (a
+string)."
+  (setq bookmark  (bmkp-get-bookmark bookmark))
+  (and (bmkp-file-bookmark-p bookmark)
+       (let* ((file   (bookmark-get-filename bookmark))
+              (fname  (file-name-nondirectory (if (file-directory-p file)
+                                                  (directory-file-name file)
+                                                file))))
+         (string= (if prefix (concat prefix fname) fname) (bmkp-bookmark-name-from-record bookmark)))))
+
+(defun bmkp-bookmark-file-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is a bookmark-file bookmark.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (eq (bookmark-get-handler bookmark) 'bmkp-jump-bookmark-file))
+
+(defun bmkp-bookmark-list-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is a bookmark-list bookmark.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (eq (bookmark-get-handler bookmark) 'bmkp-jump-bookmark-list))
+
+(defun bmkp-desktop-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is a desktop bookmark.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (eq (bookmark-get-handler bookmark) 'bmkp-jump-desktop))
+
+;; Note: To avoid remote access, if bookmark does not have the Dired handler, then we insist
+;; that it be for a local directory.  IOW, we do not include remote directories that were not
+;; bookmarked by Bookmark+ (and so do not have the Dired handler).
+(defun bmkp-dired-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is a Dired bookmark.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (or (eq (bookmark-get-handler bookmark) 'bmkp-jump-dired)
+      (bmkp-local-directory-bookmark-p bookmark)))
+
+(defun bmkp-dired-this-dir-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is a Dired bookmark for the `default-directory'.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (and (bmkp-dired-bookmark-p bookmark)
+       (let ((dir  (file-name-directory (bookmark-get-filename bookmark))))
+         (bmkp-same-file-p dir default-directory))))
+
+(defun bmkp-dired-wildcards-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK bookmarks a Dired buffer with wildcards.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (setq bookmark  (bmkp-get-bookmark bookmark))
+  (and (bmkp-dired-bookmark-p bookmark)
+       (let ((file  (bookmark-get-filename bookmark)))
+         (and (stringp file)  (bmkp-string-match-p (regexp-quote "*") file)))))
+
+(when (> emacs-major-version 24)        ; Emacs 25+
+
+  (defun bmkp-eww-bookmark-p (bookmark)
+    "Return non-nil if BOOKMARK is an EWW bookmark.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+    (eq (bookmark-get-handler bookmark) 'bmkp-jump-eww))
+
+  )
+
+(defun bmkp-file-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK bookmarks a file or directory.
+This excludes bookmarks of a more specific kind (e.g. Info, Gnus).
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (let* ((filename   (bookmark-get-filename bookmark))
+         (nonfile-p  (equal filename bmkp-non-file-filename))
+         (handler    (bookmark-get-handler bookmark)))
+    (and filename  (not nonfile-p)
+         (or (not handler)
+             (memq handler bmkp-file-bookmark-handlers)
+             (equal handler (bmkp-default-handler-for-file filename)))
+         (not (bookmark-prop-get bookmark 'info-node))))) ; Emacs 20-21 Info: no handler.
+
+(defun bmkp-file-this-dir-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK bookmarks file/subdir in `default-directory'.
+This excludes bookmarks of a more specific kind (e.g. Info, Gnus).
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (setq bookmark  (bmkp-get-bookmark bookmark 'NOERROR))
+  (and bookmark
+       (bmkp-file-bookmark-p bookmark)
+       (bmkp-same-file-p (file-name-directory (bookmark-get-filename bookmark)) default-directory)))
+
+(defun bmkp-flagged-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is flagged for deletion in `*Bookmark List*'.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (setq bookmark  (bmkp-get-bookmark bookmark))
+  (memq bookmark bmkp-flagged-bookmarks))
+
+(defun bmkp-function-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is a function bookmark.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (eq (bookmark-get-handler bookmark) 'bmkp-jump-function))
+
+(defun bmkp-gnus-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is a Gnus bookmark.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (memq (bookmark-get-handler bookmark)
+        '(gnus-summary-bookmark-jump bmkp-jump-gnus bmkext-jump-gnus)))
+
+(defun bmkp-icicles-search-hits-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK records a list of Icicles search hits.
+BOOKMARK is a bookmark name or a bookmark record.
+
+An Icicles search-hits bookmark is shown in the bookmark-list display
+with face `bmkp-no-jump', because you cannot jump to it from there."
+  (setq bookmark  (bmkp-get-bookmark bookmark))
+  (eq (bookmark-get-handler bookmark) 'bmkp-jump-icicle-search-hits))
+
+(defun bmkp-image-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is an image-file bookmark.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (or (eq (bookmark-get-handler bookmark) 'image-bookmark-jump)
+      (and (fboundp 'image-file-name-regexp) ; In `image-file.el' (Emacs 22+).
+           (bmkp-file-bookmark-p bookmark)
+           (not (bmkp-dired-bookmark-p bookmark))
+           (bmkp-string-match-p (image-file-name-regexp) (bookmark-get-filename bookmark)))))
+
+(defun bmkp-info-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is an Info bookmark.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (or (eq (bookmark-get-handler bookmark) 'Info-bookmark-jump)
+      (and (not (bookmark-get-handler bookmark))
+           (or (string= "*info*" (bmkp-get-buffer-name bookmark))
+               (bookmark-prop-get bookmark 'info-node))))) ; Emacs 20-21 - no `buffer-name' entry.
+
+(defun bmkp-kmacro-list-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is a kmacro-list bookmark.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (eq (bookmark-get-handler bookmark) 'bmkp-jump-kmacro-list))
+
+(defun bmkp-local-directory-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK bookmarks a local directory.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (let ((file  (bookmark-get-filename bookmark)))
+    (and (bmkp-local-file-bookmark-p bookmark)  (file-directory-p file))))
+
+(defun bmkp-local-file-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK bookmarks a local file or directory.
+This excludes bookmarks of a more specific kind (e.g. Info, Gnus).
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (and (bmkp-file-bookmark-p bookmark)  (not (bmkp-remote-file-bookmark-p bookmark))))
+
+(defun bmkp-local-non-dir-file-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK bookmarks a local nondirectory file.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (let ((file  (bookmark-get-filename bookmark)))
+    (and (bmkp-local-file-bookmark-p bookmark)  (not (file-directory-p file)))))
+
+(defun bmkp-buffer-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK bookmarks a non-file buffer.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (and (bmkp-get-buffer-name bookmark)
+       (let ((filep  (bookmark-get-filename bookmark)))
+         (or (not filep)  (equal filep bmkp-non-file-filename)))))
+
+(defun bmkp-man-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is a `man' page bookmark.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (memq (bookmark-get-handler bookmark) '(bmkp-jump-man bmkp-jump-woman
+                                          bmkext-jump-man bmkext-jump-woman)))
+
+(defun bmkp-marked-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is a marked bookmark in `*Bookmark List*'.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (unless (stringp bookmark) (setq bookmark  (bmkp-bookmark-name-from-record bookmark)))
+  (bmkp-bookmark-name-member bookmark bmkp-bmenu-marked-bookmarks))
+
+(defun bmkp-modified-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is a modified bookmark.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (setq bookmark  (bmkp-get-bookmark bookmark))
+  (memq bookmark bmkp-modified-bookmarks))
+
+(defun bmkp-navlist-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is in the current navigation list.
+BOOKMARK is a bookmark name or a bookmark record."
+  (setq bookmark  (bmkp-get-bookmark bookmark))
+  (memq bookmark bmkp-nav-alist))
+
+(defun bmkp-non-dir-file-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK bookmarks a nondirectory file.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (let ((file  (bookmark-get-filename bookmark)))
+    (and (bmkp-file-bookmark-p bookmark)  (not (file-directory-p file)))))
+
+(defun bmkp-non-file-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is a non-file bookmark (e.g *scratch*).
+This excludes bookmarks of a more specific kind (e.g. Info, Gnus).
+It includes bookmarks to existing buffers, as well as bookmarks
+defined for buffers that do not currently exist.
+
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (let* ((filename   (bookmark-get-filename bookmark))
+         (nonfile-p  (equal filename bmkp-non-file-filename)))
+    (and (bmkp-get-buffer-name bookmark)
+         (or (not filename)  nonfile-p
+             ;; Ensure not remote before calling `file-exists-p'.  (Do not prompt for password.)
+             (and (not (bmkp-file-remote-p filename))  (not (file-exists-p filename))))
+         (not (bookmark-get-handler bookmark)))))
+
+(defun bmkp-non-invokable-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is a non-invokable bookmark.
+That is, jumping to it has no effect, because its handler is `ignore'.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'.
+
+A non-invokable bookmark is shown in the bookmark-list display with
+face `bmkp-no-jump', because you cannot jump to it."
+  (eq (bookmark-get-handler bookmark) 'ignore))
+
+(defun bmkp-orphaned-file-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is an orphaned file or directory bookmark.
+This means that the file recorded for BOOKMARK does not exist or is
+not readable.  But a Dired bookmark with wildcards in the file name is
+assumed to be readable.
+
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (setq bookmark  (bmkp-get-bookmark bookmark))
+  (and (bmkp-file-bookmark-p bookmark)
+       (if (bmkp-dired-bookmark-p bookmark)
+           (and (not (bmkp-dired-wildcards-bookmark-p bookmark))
+                (not (file-readable-p (bookmark-get-filename bookmark))))
+         (not (file-readable-p (bookmark-get-filename bookmark))))))
+
+(defun bmkp-orphaned-local-file-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is an orphaned local-file bookmark.
+This means that the file name recorded for BOOKMARK is not remote, and
+the file does not exist or is not readable.  But a Dired bookmark with
+wildcards in the file name is assumed to be readable.
+
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (setq bookmark  (bmkp-get-bookmark bookmark))
+  (and (bmkp-local-file-bookmark-p bookmark)
+       (if (bmkp-dired-bookmark-p bookmark)
+           (and (not (bmkp-dired-wildcards-bookmark-p bookmark))
+                (not (file-readable-p (bookmark-get-filename bookmark))))
+         (not (file-readable-p (bookmark-get-filename bookmark))))))
+
+(defun bmkp-orphaned-remote-file-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is an orphaned remote-file bookmark.
+This means that the file name recorded for BOOKMARK is remote, and the
+file does not exist or is not readable.  But a Dired bookmark with
+wildcards in the file name is assumed to be readable.
+
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (setq bookmark  (bmkp-get-bookmark bookmark))
+  (and (bmkp-remote-file-bookmark-p bookmark)
+       (if (bmkp-dired-bookmark-p bookmark)
+           (and (not (bmkp-dired-wildcards-bookmark-p bookmark))
+                (not (file-readable-p (bookmark-get-filename bookmark))))
+         (not (file-readable-p (bookmark-get-filename bookmark))))))
+
+(defun bmkp-region-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK has region information.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (and (bmkp-get-end-position bookmark)
+       (bookmark-get-position bookmark)
+       (/= (bookmark-get-position bookmark) (bmkp-get-end-position bookmark))))
+
+(defun bmkp-remote-file-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK bookmarks a remote file or directory.
+This includes remote Dired bookmarks, but otherwise excludes bookmarks
+with handlers (e.g. Info, Gnus).
+
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (let* ((handler   (bookmark-get-handler bookmark))
+         (file      (bookmark-get-filename bookmark))
+         (rem-file  (and file  (bmkp-file-remote-p file))))
+    (and rem-file  (or (not handler)  (eq handler 'bmkp-jump-dired)))))
+
+(defun bmkp-remote-non-dir-file-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK bookmarks a remote nondirectory file.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (let ((file  (bookmark-get-filename bookmark)))
+    (and (bmkp-remote-file-bookmark-p bookmark)  (not (file-directory-p file)))))
+
+(defun bmkp-snippet-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is a snippet bookmark.
+This means that it records a snippet of text and that jumping to it
+copies that text to the `kill-ring'.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (setq bookmark  (bmkp-get-bookmark bookmark))
+  (eq (bookmark-get-handler bookmark) 'bmkp-jump-snippet))
+
+(defun bmkp-temporary-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is temporary.
+This means that it has a non-nil `bmkp-temp' entry.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (setq bookmark  (bmkp-get-bookmark bookmark 'NOERROR))
+  (and bookmark  (bookmark-prop-get bookmark 'bmkp-temp)))
+
+(defun bmkp-this-buffer-p (bookmark)
+  "Return non-nil if BOOKMARK's buffer is the current buffer.
+But return nil if BOOKMARK has an associated file, but it is not the
+ buffer's file.
+And return nil for bookmarks, such as desktops, that are not really
+ associated with a buffer, even if they have a `buffer-name' entry.
+
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (and (let ((this-file  (condition-case nil (bookmark-buffer-file-name) (error nil)))
+             (bmk-file   (and (bmkp-file-bookmark-p bookmark)  (bookmark-get-filename bookmark))))
+         ;; Two possibilities:
+         ;; * Neither buffer nor bookmark has a file, and the buffer names are the same.
+         ;; * Both have files, and they are the same file.
+         (or (and (not this-file)  (not bmk-file)  (equal (bmkp-get-buffer-name bookmark) (buffer-name)))
+             (and this-file  bmk-file  (bmkp-same-file-p this-file bmk-file))))
+       ;; If the buffer to check is from EWW, the buffer URL must match the bookmark URL.
+       (or (not (eq major-mode 'eww-mode))
+           (and (fboundp 'bmkp-eww-url)  (equal (bookmark-location bookmark) (bmkp-eww-url)))) ; Emacs 25+
+       (not (bmkp-desktop-bookmark-p        bookmark))
+       (not (bmkp-bookmark-file-bookmark-p  bookmark))
+       (not (bmkp-sequence-bookmark-p       bookmark))
+       (not (bmkp-function-bookmark-p       bookmark))
+       (not (bmkp-variable-list-bookmark-p  bookmark))))
+
+(defun bmkp-this-file-p (bookmark)
+  "Return non-nil if BOOKMARK's file is the visited file.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (let ((bmk-file   (and (bmkp-file-bookmark-p bookmark)  (bookmark-get-filename bookmark)))
+        (this-file  (or (and (buffer-file-name)  (bookmark-buffer-file-name))
+                        (and (eq major-mode 'dired-mode)  (if (consp dired-directory)
+                                                              (car dired-directory)
+                                                            dired-directory)))))
+    (and bmk-file  this-file  (bmkp-same-file-p this-file bmk-file))))
+
+(defun bmkp-last-specific-buffer-p (bookmark)
+  "Return t if BOOKMARK's `buffer-name' is `bmkp-last-specific-buffer'.
+But return nil for bookmarks, such as desktops, that are not really
+associated with a buffer, even if they have a `buffer-name' entry.
+It does not matter whether the buffer exists.
+
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (let ((buf  (bmkp-get-buffer-name bookmark)))
+    (and buf  (string= buf bmkp-last-specific-buffer)
+         (not (bmkp-desktop-bookmark-p        bookmark))
+         (not (bmkp-bookmark-file-bookmark-p  bookmark))
+         (not (bmkp-sequence-bookmark-p       bookmark))
+         (not (bmkp-function-bookmark-p       bookmark))
+         (not (bmkp-variable-list-bookmark-p  bookmark)))))
+
+(defun bmkp-last-specific-file-p (bookmark)
+  "Return t if BOOKMARK's `filename' is `bmkp-last-specific-file'.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (let ((file  (bookmark-get-filename bookmark)))
+    (and file  (bmkp-same-file-p file bmkp-last-specific-file))))
+
+(defun bmkp-sequence-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is a sequence bookmark.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (eq (bookmark-get-handler bookmark) 'bmkp-jump-sequence))
+
+(defun bmkp-some-marked-p (alist)
+  "Return non-nil if ALIST is nonempty and includes a marked bookmark."
+  (catch 'break (dolist (i  alist)  (and (bmkp-marked-bookmark-p i)  (throw 'break t)))))
+
+(defun bmkp-some-unmarked-p (alist)
+  "Return non-nil if ALIST is nonempty and includes an unmarked bookmark."
+  (catch 'break (dolist (i  alist)  (and (not (bmkp-marked-bookmark-p i))  (throw 'break t)))))
+
+(defun bmkp-url-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is a URL bookmark.
+This means that it satifies `bmkp-eww-bookmark-p' (Emacs 25+),
+`bmkp-w3m-bookmark-p', or `bmkp-url-browse-bookmark-p'.
+
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (or (and (fboundp 'bmkp-eww-bookmark-p)  (bmkp-eww-bookmark-p bookmark))
+      (bmkp-w3m-bookmark-p bookmark)
+      (bmkp-url-browse-bookmark-p bookmark)))
+
+(defun bmkp-url-browse-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is a `browse-url' bookmark.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (eq (bookmark-get-handler bookmark) 'bmkp-jump-url-browse))
+
+(defun bmkp-variable-list-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is a variable-list bookmark.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (eq (bookmark-get-handler bookmark) 'bmkp-jump-variable-list))
+
+(defun bmkp-w3m-bookmark-p (bookmark)
+  "Return non-nil if BOOKMARK is a W3M bookmark.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (memq (bookmark-get-handler bookmark) '(bmkp-jump-w3m bmkext-jump-w3m)))
+
+
+
+
+
+;;(@* "General Utility Functions")
+;;  *** General Utility Functions ***
+
+(when (and (fboundp 'cl-puthash)  (not (fboundp 'puthash))) ; Emacs 20 with `cl-extra.el' loaded.
+  (defalias 'puthash 'cl-puthash))
+
+(if (fboundp 'puthash)                  ; Emacs 21+, or Emacs 20 with `cl-extra.el' loaded.
+    (defun bmkp-remove-dups (sequence &optional test)
+      "Copy of SEQUENCE with duplicate elements removed.
+Optional arg TEST is the test function.  If nil, test with `equal'.
+See `make-hash-table' for possible values of TEST."
+      (setq test  (or test  #'equal))
+      (let ((htable  (make-hash-table :test test)))
+        (loop for elt in sequence
+              unless (gethash elt htable)
+              do     (puthash elt elt htable)
+              finally return (loop for i being the hash-values in htable collect i))))
+
+  (defun bmkp-remove-dups (list &optional use-eq)
+    "Copy of LIST with duplicate elements removed.
+Test using `equal' by default, or `eq' if optional USE-EQ is non-nil."
+    (let ((tail  list)
+          new)
+      (while tail
+        (unless (if use-eq (memq (car tail) new) (member (car tail) new))
+          (push (car tail) new))
+        (pop tail))
+      (nreverse new))))
+
+(defun bmkp-unpropertized-string (string)
+  "Return a copy of STRING, but with properties removed.
+Does not change the original STRING."
+  (let ((strg  (copy-sequence string)))
+    (set-text-properties 0 (length strg) () strg)
+    strg))
+
+;; For a name propertized with `bmkp-full-record', this is similar to `bmkp-assoc-delete-all'.
+(defun bmkp-delete-bookmark-name-from-list (delname bnames)
+  "Delete names that represent the same bookmark as DELNAME from BNAMES.
+This means that they are `string=' and they either have no property
+`bmkp-full-record' or that property has the same value.
+Return the modified list BNAMES."
+  ;; $$$$$$ Can we change `equal' to `eq' everywhere here?
+  (let ((delprop  (get-text-property 0 'bmkp-full-record delname))
+        bmkprop)
+    (if (not delprop)
+        (setq bnames  (delete delname bnames)) ; Unpropertized - just use `delete'.
+      ;; Propertized.  Delete names that are `string=' and have the same property value or none.
+      (while (and bnames  (string= delname (car bnames)) ; Delete those at list beginning.
+                  (or (not (setq bmkprop  (get-text-property 0 'bmkp-full-record (car bnames))))
+                      (equal delprop bmkprop)))
+        (setq bnames  (cdr bnames)))
+      (let ((tail  bnames)              ; Delete those not at list beginning.
+            tail-cdr)
+        (while (setq tail-cdr  (cdr tail))
+          (if (and (car tail-cdr)
+                   (string= delname (car tail-cdr))
+                   (or (not (setq bmkprop  (get-text-property 0 'bmkp-full-record (car tail-cdr))))
+                       (equal delprop bmkprop)))
+              (setcdr tail  (cdr tail-cdr))
+            (setq tail  tail-cdr))))
+      bnames)))
+
+(defun bmkp-bookmark-name-member (name names)
+  "Like `member', but tests also bookmark NAME's `bmkp-full-record' property.
+Return the tail of NAMES whose car is NAME with the property match.
+If NAME has no `bmkp-full-record' property then this is just `member'.
+If NAME has property `bmkp-full-record', then test whether both:
+ a. NAME is a member of NAMES and
+ b. NAME has the same `bmkp-full-record' value as an element of NAMES."
+  ;; $$$$$$ Can we change `equal' to `eq' here?
+  (let ((prop  (get-text-property 0 'bmkp-full-record name)))
+    (if (or (null name)  (not prop))
+        (member name names)             ; Unpropertized - just use `member'.
+      (while (and names  (not (and (stringp (car names))
+                                   (string= name (car names)) ; = `bmkp-names-same-bookmark-p'.
+                                   ;; If unpropertized in NAMES, then assume it's the one.
+                                   (or (not (get-text-property 0 'bmkp-full-record (car names)))
+                                       (equal prop (get-text-property 0 'bmkp-full-record (car names)))))))
+        (setq names  (cdr names)))
+      names)))
+
+(defun bmkp-names-same-bookmark-p (name1 name2)
+  "Return non-nil if the two strings name the same bookmark.
+The strings are `string=' and their `bmkp-full-record' property values
+for the first character are `equal'."
+
+  ;; $$$$$$ Can we change `equal' to `eq' here?
+  (and (string= name1 name2)
+       (equal (get-text-property 0 'bmkp-full-record name1)
+              (get-text-property 0 'bmkp-full-record name2))))
+
+(defun bmkp-read-buffers ()
+"Read names of buffers associated with bookmarks.
+Invoke `bmkp-completing-read-buffer-name' repeatedly till input is empty."
+  (let ((buffs  ())
+        buff)
+    (while (and (setq buff  (bmkp-completing-read-buffer-name 'ALLOW-EMPTY))  (not (string= "" buff)))
+      (add-to-list 'buffs buff))
+    buffs))
+
+(defun bmkp-read-files ()
+  "Read names of files associated with bookmarks.
+Invoke `bmkp-completing-read-file-name' repeatedly till input is empty."
+  (let ((use-file-dialog  nil)
+        (files            ())
+        file)
+    (while (and (setq file  (bmkp-completing-read-file-name 'ALLOW-EMPTY))  (not (string= "" file)))
+      (add-to-list 'files file))
+    files))
+
+(defun bmkp-remove-if (pred xs)
+  "A copy of list XS with no elements that satisfy predicate PRED."
+  (let ((result  ()))
+    (dolist (x  xs)  (unless (funcall pred x) (push x result)))
+    (nreverse result)))
+
+(defun bmkp-remove-if-not (pred xs)
+  "A copy of list XS with only elements that satisfy predicate PRED."
+  (let ((result  ()))
+    (dolist (x  xs)  (when (funcall pred x) (push x result)))
+    (nreverse result)))
+
+;; Similar to `every' in `cl-extra.el', without non-list sequences and multiple sequences.
+(defun bmkp-every (predicate list)
+  "Return t if PREDICATE is true for all elements of LIST; else nil."
+  (while (and list  (funcall predicate (car list)))  (setq list  (cdr list)))
+  (null list))
+
+;; Same as `zz-some' in `zones.el'.
+;; This is NOT the same as `some' in `cl-extra.el', even without non-list sequences and multiple sequences.
+;;
+;; If PREDICATE is satisfied by a list element ELEMENT, so that it returns a non-nil value VALUE for ELEMENT,
+;; then this returns the cons (ELEMENT . VALUE).  It does not return just VALUE.
+(defun bmkp-some (predicate list)
+  "Return non-nil if PREDICATE applied to some element of LIST is true.
+The value returned is a cons, (ELEMENT . VALUE), where ELEMENT is the
+first list element that satisfies PREDICATE and VALUE is the value of
+PREDICATE applied to ELEMENT."
+  (let (elt val)
+    (catch 'bmkp-some
+      (while list
+        (when (setq val  (funcall predicate (setq elt  (pop list))))
+          (throw 'bmkp-some (cons elt val))))
+      nil)))
+
+;; From `cl-seq.el', function `union', without keyword treatment.
+;; (Same as `icicle-set-union' in `icicles-fn.el'.)
+(defun bmkp-set-union (list1 list2)
+  "Combine LIST1 and LIST2 using a set-union operation.
+The result list contains all items that appear in either LIST1 or
+LIST2.  Comparison is done using `equal'.  This is a non-destructive
+function; it copies the data if necessary."
+  (cond ((null list1)         list2)
+        ((null list2)         list1)
+        ((equal list1 list2)  list1)
+        (t
+         (unless (>= (length list1) (length list2))
+           (setq list1  (prog1 list2 (setq list2  list1)))) ; Swap them.
+         (while list2
+           (unless (member (car list2) list1)  (setq list1  (cons (car list2) list1)))
+           (setq list2  (cdr list2)))
+         list1)))
+
+(defun bmkp-upcase (string)
+  "`upcase', but in case of error, return original STRING.
+This works around an Emacs 20 problem that occurs if STRING contains
+binary data (weird chars)."
+  (condition-case nil (upcase string) (error string)))
+
+;; Thx to Michael Heerdegen and Michael Albinus for help with this one.
+(defun bmkp-same-file-p (file1 file2)
+  "Return non-nil if FILE1 and FILE2 name the same file.
+If either name is not absolute, then it is expanded relative to
+`default-directory' for the test."
+  (let* ((remote1        (bmkp-file-remote-p file1))
+         (remote2        (bmkp-file-remote-p file2))
+         (ignore-case-p  (and (not remote1)  (not remote2) ; Assume case-sensitive if remote.
+                              (if (boundp 'read-file-name-completion-ignore-case)
+                                  (eval (car (get 'read-file-name-completion-ignore-case
+                                                  'standard-value)))
+                                ;; From the Emacs 24 definition of `read-file-name-completion-ignore-case'.
+                                (memq system-type '(ms-dos windows-nt darwin cygwin))))))
+    (and (equal remote1 remote2)
+         (if (fboundp 'file-equal-p)
+             (file-equal-p file1 file2)
+           (let ((ft1  (file-truename (expand-file-name file1)))
+                 (ft2  (file-truename (expand-file-name file2))))
+             (eq t (compare-strings ft1 0 (length ft1) ft2 0 (length ft2) ignore-case-p)))))))
+
+;;; $$$$$$
+;;; (defun bmkp-same-file-p (file1 file2)
+;;;   "Return non-nil if FILE1 and FILE2 name the same file.
+;;; If either name is not absolute, then it is expanded relative to
+;;; `default-directory' for the test."
+;;;   (and (equal (bmkp-file-remote-p file1) (bmkp-file-remote-p file2))
+;;;        (string= (file-truename (expand-file-name file1))
+;;;                 (file-truename (expand-file-name file2)))))
+
+;;; $$$$$$
+;;; (defun bmkp-file-remote-p (file-name)
+;;;   "Returns non-nil if string FILE-NAME is likely to name a remote file."
+;;;   (if (fboundp 'file-remote-p)
+;;;       (file-remote-p file-name)
+;;;     (and (fboundp 'ffap-file-remote-p)  (ffap-file-remote-p file-name))))
+
+(defun bmkp-file-remote-p (file)
+  "Test whether FILE specifies a location on a remote system.
+Return nil or a string identifying the remote connection (ideally a
+prefix of FILE).
+
+A file is considered remote if accessing it is likely to be slower or
+less reliable than accessing local files.
+
+This is `file-remote-p', if that function is available.  If not, use a
+simple match against rough remote file syntax: `/...:'.
+
+Unless `file-remote-p' is available and FILE has a `file-remote-p'
+handler that opens a remote connection, `bmkp-file-remote-p' does not
+open a remote connection."
+  (if (fboundp 'file-remote-p)
+      (file-remote-p file)
+    (and (stringp file)  (string-match "\\`/[^/]+:" file)  (match-string 0 file))))
+
+(defun bmkp-float-time (&optional specified-time)
+  "Same as `float-time'.  (Needed for Emacs 20.)"
+  (if (fboundp 'float-time)
+      (float-time specified-time)
+    (unless specified-time (setq specified-time  (current-time)))
+    (+ (* (float (nth 0 specified-time)) (expt 2 16))  (nth 1 specified-time))))
+
+(defun bmkp-string-less-case-fold-p (s1 s2)
+  "Like `string-lessp', but respect `case-fold-search'."
+  (when case-fold-search (setq s1  (bmkp-upcase s1)
+                               s2  (bmkp-upcase s2)))
+  (string-lessp s1 s2))
+
+(defun bmkp-make-plain-predicate (pred &optional final-pred)
+  "Return a plain predicate that corresponds to component-predicate PRED.
+PRED and FINAL-PRED correspond to their namesakes in
+`bmkp-sort-comparer' (which see).
+
+PRED should return `(t)', `(nil)', or nil.
+
+Optional arg FINAL-PRED is the final predicate to use if PRED cannot
+decide (returns nil).  If FINAL-PRED is nil, then `bmkp-alpha-p', the
+plain-predicate equivalent of `bmkp-alpha-cp' is used as the final
+predicate."
+  `(lambda (b1 b2) (let ((res  (funcall ',pred b1 b2)))
+                     (if res (car res) (funcall ',(or final-pred  'bmkp-alpha-p) b1 b2)))))
+
+(defun bmkp-repeat-command (command)
+  "Repeat COMMAND."
+  (require 'repeat)                   ; Define its vars before we let-bind them.
+  (let ((repeat-previous-repeated-command  command)
+        (repeat-message-function           #'ignore)
+        (last-repeatable-command           'repeat))
+    (repeat nil)))
+
+
+;;; If you need this for some reason, uncomment it.
+;;; (defun bmkp-fix-bookmark-alist-and-save ()
+;;;   "Update format of `bookmark-default-file' created in summer of 2009.
+;;; You DO NOT NEED THIS, unless you happen to have used `bookmark+.el' in
+;;; the summer of 2009 to create non-file bookmarks.  If you did that,
+;;; then some of those bookmarks might cause vanilla Emacs (emacs -Q) to
+;;; raise an error.  You can use this command to fix that problem: it
+;;; modifies your existing `bookmark-default-file' (`~/.emacs.bmk'), after
+;;; backing up that file (suffixing the name with \"_saveNUMBER\")."
+;;;   (interactive)
+;;;   (require 'cl)                         ; For `gensym'
+;;;   (if (not (yes-or-no-p
+;;;              "This will modify your bookmark file, after backing it up.  OK? "))
+;;;       (message "OK, nothing done")
+;;;     (bookmark-maybe-load-default-file)
+;;;     (let ((bkup-file  (concat bookmark-default-file "_" (symbol-name (gensym "save")))))
+;;;       (when (condition-case err
+;;;                 (progn
+;;;                   (with-current-buffer (let ((enable-local-variables  ()))
+;;;                                          (find-file-noselect bookmark-default-file))
+;;;                     (write-file bkup-file))
+;;;                   (dolist (bmk  bookmark-alist)
+;;;                     (let ((fn-tail  (member '(filename) bmk))
+;;;                           (hdlr     (bookmark-get-handler (car bmk))))
+;;;                       (cond (fn-tail
+;;;                              (setcar fn-tail (cons 'filename bmkp-non-file-filename)))
+;;;                             ((and (eq hdlr 'bmkp-jump-gnus)
+;;;                                   (not (assoc 'filename bmk)))
+;;;                              (setcdr bmk (cons (cons 'filename bmkp-non-file-filename)
+;;;                                                (cdr bmk)))))))
+;;;                   t)                    ; Be sure `dolist' exit with t to allow saving.
+;;;               (error (error "No changes made. %s" (error-message-string err))))
+;;;         (bookmark-save)
+;;;         (message "Bookmarks file fixed.  Old version is `%s'" bkup-file)))))
+
+
+;;(@* "Bookmark Entry Access Functions")
+;;  *** Bookmark Entry Access Functions ***
+
+(defun bmkp-get-buffer-name (bookmark)
+  "Return the `buffer-name' entry for BOOKMARK.
+BOOKMARK is a bookmark name or a bookmark record."
+  (bookmark-prop-get bookmark 'buffer-name))
+
+(defun bmkp-get-end-position (bookmark)
+  "Return the `end-position' entry for BOOKMARK.
+BOOKMARK is a bookmark name or a bookmark record."
+  (bookmark-prop-get bookmark 'end-position))
+
+(defun bmkp-get-visits-count (bookmark)
+  "Return the `visits' count for BOOKMARK.
+BOOKMARK is a bookmark name or a bookmark record."
+  (bookmark-prop-get bookmark 'visits))
+
+(defun bmkp-get-visit-time (bookmark)
+  "Return the `time' value for BOOKMARK.
+BOOKMARK is a bookmark name or a bookmark record."
+  ;; Should just be a prop-get, but when first implemented, we used a float
+  ;; instead of a time cons, so we need to convert any such obsolete recorded times.
+  (let ((vt  (bookmark-prop-get bookmark 'time)))
+    (when (numberp vt)                  ; Convert mid-2009 time values (floats) to cons form.
+      (setq vt  (if (boundp 'seconds-to-time)
+                    (seconds-to-time vt)
+                  (list (floor vt 65536) ; Inlined `seconds-to-time', for Emacs 20-21.
+                        (floor (mod vt 65536))
+                        (floor (* (- vt (ffloor vt)) 1000000))))))
+    vt))
+
+
+;;(@* "Sorting - General Functions")
+;;  *** Sorting - General Functions ***
+
+(defun bmkp-sort-omit (alist &optional omit)
+  "Sort a copy of ALIST, omitting any elements whose keys are in OMIT.
+Return the copy.
+Do not sort if `bmkp-sort-comparer' is nil.
+This is a non-destructive operation: ALIST is not modified.
+
+Sorting is done using using `bmkp-sort-comparer'.
+If `bmkp-reverse-sort-p' is non-nil, then reverse the sort order.
+Keys are compared for sorting using `equal'.
+
+If optional arg OMIT is non-nil, then it is a list of keys.  Omit from
+the return value any elements with keys in the list."
+  (lexical-let ((new-alist  (bmkp-remove-omitted alist omit))
+                (sort-fn    (and bmkp-sort-comparer  (if (and (not (functionp bmkp-sort-comparer))
+                                                              (consp bmkp-sort-comparer))
+                                                         'bmkp-multi-sort
+                                                       bmkp-sort-comparer))))
+    (when sort-fn
+      (setq new-alist  (sort new-alist (if bmkp-reverse-sort-p
+                                           (lambda (a b) (not (funcall sort-fn a b)))
+                                         sort-fn))))
+    new-alist))
+
+(defun bmkp-remove-omitted (alist &optional omit)
+  "Copy of bookmark ALIST without bookmarks whose names are in list OMIT.
+Name comparison is done using `bmkp-bookmark-name-member'.
+If optional arg OMIT is non-nil, then omit from the return value any
+elements with keys in list OMIT."
+  (let ((new  ()))
+    (dolist (ii  alist)  (unless (bmkp-bookmark-name-member (car ii) omit)  (push ii new)))
+    (nreverse new)))
+
+;;; $$$$$$ No longer used.
+;;; (defun bmkp-sort-and-remove-dups (alist &optional omit)
+;;;   "Remove duplicates from a copy of ALIST, then sort it and return it.
+;;; Do not sort if `bmkp-sort-comparer' is nil.
+;;; Always remove duplicates.  Keep only the first element with a given
+;;; key.  This is a non-destructive operation: ALIST is not modified.
+
+;;; Sorting is done using using `bmkp-sort-comparer'.
+;;; If `bmkp-reverse-sort-p' is non-nil, then reverse the sort order.
+;;; Keys are compared for sorting using `equal'.
+;;; If optional arg OMIT is non-nil, then omit from the return value any
+;;; elements with keys in list OMIT."
+;;;   (lexical-let ((new-alist  (bmkp-remove-assoc-dups alist omit))
+;;;                (sort-fn  (and bmkp-sort-comparer  (if (and (not (functionp bmkp-sort-comparer))
+;;;                                                     (consp bmkp-sort-comparer))
+;;;                                                            'bmkp-multi-sort
+;;;                                                    bmkp-sort-comparer))))
+;;;     (when sort-fn
+;;;       (setq new-alist  (sort new-alist (if bmkp-reverse-sort-p
+;;;                                            (lambda (a b) (not (funcall sort-fn a b)))
+;;;                                          sort-fn))))
+;;;     new-alist))
+
+;;; KEEP this simpler version also.  This uses `run-hook-with-args-until-success', but it
+;;; does not respect `bmkp-reverse-multi-sort-p'.
+;;; (defun bmkp-multi-sort (b1 b2)
+;;;   "Try predicates in `bmkp-sort-comparer', in order, until one decides.
+;;; See the description of `bmkp-sort-comparer'."
+;;;   (let* ((preds   (append (car bmkp-sort-comparer) (cdr bmkp-sort-comparer)))
+;;;          (result  (run-hook-with-args-until-success 'preds b1 b2)))
+;;;     (if (consp result)
+;;;         (car result)
+;;;       result)))
+
+;;; $$$$$$ No longer used.
+;;; (defun bmkp-remove-assoc-dups (alist &optional omit)
+;;;   "Shallow copy of ALIST without elements that have duplicate keys.
+;;; Only the first element of those with the same key is kept.
+;;; Keys are compared using `equal'.
+;;; If optional arg OMIT is non-nil, then omit from the return value any
+;;; elements with keys in list OMIT."
+;;;   (let ((new  ()))
+;;;     (dolist (ii  alist)  (unless (or (assoc (car ii) new)  (member (car ii) omit))  (push ii new)))
+;;;     (nreverse new)))
+
+
+;; This Lisp definition respects `bmkp-reverse-multi-sort-p', and can be extended.
+(defun bmkp-multi-sort (b1 b2)
+  "Try predicates in `bmkp-sort-comparer', in order, until one decides.
+See the description of `bmkp-sort-comparer'.
+If `bmkp-reverse-multi-sort-p' is non-nil, then reverse the order for
+using multi-sorting predicates."
+  (let ((preds       (car bmkp-sort-comparer))
+        (final-pred  (cadr bmkp-sort-comparer))
+        (result      nil))
+    (when bmkp-reverse-multi-sort-p (setq preds  (reverse preds)))
+    (catch 'bmkp-multi-sort
+      (dolist (pred  preds)
+        (setq result  (funcall pred b1 b2))
+        (when (consp result)
+          (when bmkp-reverse-multi-sort-p (setq result  (list (not (car result)))))
+          (throw 'bmkp-multi-sort (car result))))
+      (and final-pred  (if bmkp-reverse-multi-sort-p
+                           (not (funcall final-pred b1 b2))
+                         (funcall final-pred b1 b2))))))
+
+
+;; The description returned is only approximate.  The effect of `bmkp-reverse-multi-sort-p' is not
+;; always intuitive, but it can often be useful.  What's not always intuitive is the placement
+;; (the order) of bookmarks that are not sorted by the predicates.
+;;
+(defun bmkp-sorting-description (order)
+  "Return a string describing sort ORDER."
+  (concat
+   (if (and order  bmkp-sort-comparer)
+       order
+     (concat (and order  (format "(%s) " order)) "turned OFF"))
+   (cond ((not bmkp-sort-comparer) nil)
+         ((not (and (consp bmkp-sort-comparer)  (consp (car bmkp-sort-comparer)))) ; Ordinary single pred.
+          (if bmkp-reverse-sort-p " (REVERSED)" ""))
+         ((not (cadr (car bmkp-sort-comparer))) ; Single predicate.
+          (if (or (and bmkp-reverse-sort-p  (not bmkp-reverse-multi-sort-p))
+                  (and bmkp-reverse-multi-sort-p  (not bmkp-reverse-sort-p)))
+              " (REVERSED)"
+            "")
+          ;; If we wanted to distinguish the two:
+          ;; (if (and bmkp-reverse-sort-p  (not bmkp-reverse-multi-sort-p))
+          ;;     "; REVERSED"
+          ;;   (if (and bmkp-reverse-multi-sort-p  (not bmkp-reverse-sort-p))
+          ;;       "; REVERSED +"
+          ;;     ""))
+          )
+         ;; At least two predicates.
+         ((and bmkp-reverse-sort-p  (not bmkp-reverse-multi-sort-p)) " (REVERSED)")
+         ((and bmkp-reverse-multi-sort-p  (not bmkp-reverse-sort-p)) " (each pred group reversed)")
+         ((and bmkp-reverse-multi-sort-p  bmkp-reverse-sort-p)       " (order of pred groups reversed)")
+         (t ""))))
+
+(defun bmkp-msg-about-sort-order (order &optional prefix-msg suffix-msg)
+  "Display a message mentioning sort ORDER and direction.
+Optional arg PREFIX-MSG is prepended to the constructed message, and
+terminated with a period.
+Similarly, SUFFIX-MSG is appended, after appending \".  \"."
+  (let ((msg  (concat "Sorting " (bmkp-sorting-description order))))
+    (when prefix-msg (setq msg  (concat prefix-msg ".  " msg)))
+    (when suffix-msg (setq msg  (concat msg ".  " suffix-msg)))
+    (message msg)))
+
+
+;;(@* "Sorting - Commands")
+;;  *** Sorting - Commands ***
+
+(defun bmkp-current-sort-order ()
+  "Current sort order or sort function, as a string, or nil if none."
+  (car (rassoc bmkp-sort-comparer bmkp-sort-orders-alist)))
+
+
+;;(@* "Sorting - General Predicates")
+;;  *** Sorting - General Predicates ***
+
+(defun bmkp-annotated-cp (b1 b2)
+  "True if bookmark B1 is annotated and bookmark B2 is not.
+Return nil if incomparable as described.
+
+Reverse the roles of B1 and B2 for a false value.
+A true value is returned as `(t)', a false value as `(nil)'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+  (setq b1  (bmkp-get-bookmark b1)
+        b2  (bmkp-get-bookmark b2))
+  (let ((m1  (bmkp-annotated-bookmark-p b1))
+        (m2  (bmkp-annotated-bookmark-p b2)))
+    (cond ((and m1 m2)  nil)
+          (m1           '(t))
+          (m2           '(nil))
+          (t            nil))))
+
+(defun bmkp-flagged-cp (b1 b2)
+  "True if bookmark B1 is flagged for deletion and bookmark B2 is not.
+Return nil if incomparable as described.
+
+Reverse the roles of B1 and B2 for a false value.
+A true value is returned as `(t)', a false value as `(nil)'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+  (setq b1  (bmkp-get-bookmark b1)
+        b2  (bmkp-get-bookmark b2))
+  (let ((m1  (bmkp-flagged-bookmark-p b1))
+        (m2  (bmkp-flagged-bookmark-p b2)))
+    (cond ((and m1 m2)  nil)
+          (m1           '(t))
+          (m2           '(nil))
+          (t            nil))))
+
+(defun bmkp-marked-cp (b1 b2)
+  "True if bookmark B1 is marked and bookmark B2 is not.
+Return nil if incomparable as described.
+
+Reverse the roles of B1 and B2 for a false value.
+A true value is returned as `(t)', a false value as `(nil)'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+  (setq b1  (bmkp-get-bookmark b1)
+        b2  (bmkp-get-bookmark b2))
+  (let ((m1  (bmkp-marked-bookmark-p b1))
+        (m2  (bmkp-marked-bookmark-p b2)))
+    (cond ((and m1 m2)  nil)
+          (m1           '(t))
+          (m2           '(nil))
+          (t            nil))))
+
+(defun bmkp-modified-cp (b1 b2)
+  "True if bookmark B1 is modified and bookmark B2 is not.
+Return nil if incomparable as described.
+
+Reverse the roles of B1 and B2 for a false value.
+A true value is returned as `(t)', a false value as `(nil)'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+  (setq b1  (bmkp-get-bookmark b1)
+        b2  (bmkp-get-bookmark b2))
+  (let ((m1  (bmkp-modified-bookmark-p b1))
+        (m2  (bmkp-modified-bookmark-p b2)))
+    (cond ((and m1 m2)  nil)
+          (m1           '(t))
+          (m2           '(nil))
+          (t            nil))))
+
+(defun bmkp-tagged-cp (b1 b2)
+  "True if bookmark B1 is tagged and bookmark B2 is not.
+Return nil if incomparable as described.
+
+Reverse the roles of B1 and B2 for a false value.
+A true value is returned as `(t)', a false value as `(nil)'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+  (setq b1  (bmkp-get-bookmark b1)
+        b2  (bmkp-get-bookmark b2))
+  (let ((m1  (bmkp-tagged-bookmark-p b1))
+        (m2  (bmkp-tagged-bookmark-p b2)))
+    (cond ((and m1 m2)  nil)
+          (m1           '(t))
+          (m2           '(nil))
+          (t            nil))))
+
+(defun bmkp-visited-more-cp (b1 b2)
+  "True if bookmark B1 was visited more often than B2.
+Return nil if incomparable as described.
+
+True also if B1 was visited but B2 was not.
+Reverse the roles of B1 and B2 for a false value.
+A true value is returned as `(t)', a false value as `(nil)'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+  (setq b1  (bmkp-get-bookmark b1)
+        b2  (bmkp-get-bookmark b2))
+  (let ((v1  (bmkp-get-visits-count b1))
+        (v2  (bmkp-get-visits-count b2)))
+    (cond ((and v1 v2)
+           (cond ((> v1 v2)  '(t))
+                 ((> v2 v1)  '(nil))
+                 (t          nil)))
+          (v1                '(t))
+          (v2                '(nil))
+          (t                 nil))))
+
+(defun bmkp-bookmark-creation-cp (b1 b2)
+  "True if bookmark B1 was created more recently than B2.
+Return nil if incomparable as described.
+
+True also if B1 has a `created' entry but B2 has none.
+Reverse the roles of B1 and B2 for a false value.
+A true value is returned as `(t)', a false value as `(nil)'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+  (setq b1  (bmkp-get-bookmark b1)
+        b2  (bmkp-get-bookmark b2))
+  (let ((t1  (bookmark-prop-get b1 'created))
+        (t2  (bookmark-prop-get b2 'created)))
+    (cond ((and t1 t2)
+           (setq t1  (bmkp-float-time t1)
+                 t2  (bmkp-float-time t2))
+           (cond ((> t1 t2)  '(t))
+                 ((> t2 t1)  '(nil))
+                 (t          nil)))
+          (t1                '(t))
+          (t2                '(nil))
+          (t                 nil))))
+
+;; Not used currently.
+(defun bmkp-same-creation-time-p (b1 b2)
+  "Return non-nil if `B1 and B2 have same `created' entry.
+If neither has a `created' entry (vanilla bookmarks), then return
+non-nil if the full bookmarks are `equal'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+  (let ((time1  (bookmark-prop-get b1 'created))
+        (time2  (bookmark-prop-get b2 'created)))
+    (if (or time1  time2) (equal time1 time2) (equal b1 b2))))
+
+(defun bmkp-bookmark-last-access-cp (b1 b2)
+  "True if bookmark B1 was visited more recently than B2.
+Return nil if incomparable as described.
+
+True also if B1 was visited but B2 was not.
+Reverse the roles of B1 and B2 for a false value.
+A true value is returned as `(t)', a false value as `(nil)'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+  (setq b1  (bmkp-get-bookmark b1)
+        b2  (bmkp-get-bookmark b2))
+  (let ((t1  (bmkp-get-visit-time b1))
+        (t2  (bmkp-get-visit-time b2)))
+    (cond ((and t1 t2)
+           (setq t1  (bmkp-float-time t1)
+                 t2  (bmkp-float-time t2))
+           (cond ((> t1 t2)  '(t))
+                 ((> t2 t1)  '(nil))
+                 (t          nil)))
+          (t1                '(t))
+          (t2                '(nil))
+          (t                 nil))))
+
+(defun bmkp-buffer-last-access-cp (b1 b2)
+  "True if bookmark B1's buffer or file was visited more recently than B2's.
+Return nil if incomparable as described.
+
+A bookmark to an existing buffer sorts before a file bookmark, even if
+the buffer has not been visited during this session.
+
+True also if B1 has a buffer but B2 does not.
+Reverse the roles of B1 and B2 for a false value.
+A true value is returned as `(t)', a false value as `(nil)'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+  (setq b1  (bmkp-get-bookmark b1)
+        b2  (bmkp-get-bookmark b2))
+  (let ((buf1  (bmkp-get-buffer-name b1))
+        (buf2  (bmkp-get-buffer-name b2))
+        f1 f2 t1 t2)
+    (setq buf1  (and buf1  (get-buffer buf1))
+          buf2  (and buf2  (get-buffer buf2)))
+    (cond ((and buf1 buf2)              ; Both buffers exist.   See whether they were accessed.
+           (when buf1 (setq buf1  (member buf1 (buffer-list))
+                            buf1  (length buf1)))
+           (when buf2 (setq buf2  (member buf2 (buffer-list))
+                            buf2  (length buf2)))
+           (cond ((and buf1 buf2)       ; Both were accessed.  Priority to most recent access.
+                  (cond ((< buf1 buf2)  '(t))
+                        ((< buf2 buf1)  '(nil))
+                        (t              nil)))
+                 (buf1                  '(t)) ; Only buf1 was accessed.
+                 (buf2                  '(nil)) ; Only buf2 was accessed.
+                 (t                     nil))) ; Neither was accessed.
+
+          (buf1                         '(t)) ; Only buf1 exists.
+          (buf2                         '(nil)) ; Only buf2 exists.
+          (t                            nil)))) ; Neither buffer exists
+
+;; EWW.  Not used yet.
+(when (> emacs-major-version 24)        ; Emacs 25
+
+  (defun bmkp-eww-cp (b1 b2)
+    "True if bookmark B1 sorts as an EWW URL bookmark before B2.
+Return nil if neither sorts before the other.
+
+Two EWW URL bookmarks are compared alphabetically, by their URLs.
+True also if B1 is a EWW bookmark but B2 is not.
+Reverse the roles of B1 and B2 for a false value.
+A true value is returned as `(t)', a false value as `(nil)'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+    (setq b1  (bmkp-get-bookmark b1)
+          b2  (bmkp-get-bookmark b2))
+    (let ((e1  (bmkp-eww-bookmark-p b1))
+          (e2  (bmkp-eww-bookmark-p b2)))
+      (cond ((and e1 e2)
+             (setq e1  (bookmark-get-filename b1)
+                   e2  (bookmark-get-filename b2))
+             (cond ((string-lessp e1 e2)  '(t))
+                   ((string-lessp e2 e1)  '(nil))
+                   (t                     nil)))
+            (e1                           '(t))
+            (e2                           '(nil))
+            (t                            nil))))
+
+  )
+
+(defun bmkp-handler-cp (b1 b2)
+  "True if bookmark B1's handler name sorts alphabetically before B2's.
+Return nil if neither sorts before the other.
+
+Two bookmarks with handlers are compared alphabetically, by their
+handler-function names, respecting `case-fold-search'.
+True also if B1 has a handler but B2 has not.
+Reverse the roles of B1 and B2 for a false value.
+A true value is returned as `(t)', a false value as `(nil)'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+  (setq b1  (bmkp-get-bookmark b1)
+        b2  (bmkp-get-bookmark b2))
+  (let ((h1  (bookmark-get-handler b1))
+        (h2  (bookmark-get-handler b2)))
+    (cond ((and h1 h2 (symbolp h1) (symbolp h2))
+           ;; Pretend woman bookmarks are man bookmarks, to keep them together.
+           (when (eq h1 'bmkp-jump-woman) (setq h1  'bmkp-jump-man))
+           (when (eq h2 'bmkp-jump-woman) (setq h2  'bmkp-jump-man))
+           (setq h1  (symbol-name h1)
+                 h2  (symbol-name h2))
+           (when case-fold-search (setq h1  (bmkp-upcase h1)
+                                        h2  (bmkp-upcase h2)))
+           (cond ((string-lessp h1 h2)  '(t))
+                 ((string-lessp h2 h1)  '(nil))
+                 (t                     nil)))
+          (h1                           '(t))
+          (h2                           '(nil))
+          (t                            nil))))
+
+;; Keep the alias for a while, in case someone has it referenced in a state file.
+(defalias 'bmkp-info-cp 'bmkp-info-node-name-cp)
+(bmkp-make-obsolete 'bmkp-info-cp 'bmkp-info-node-name-cp "2017-07-03")
+
+(defun bmkp-info-node-name-cp (b1 b2)
+  "True if bookmark B1 sorts as an Info bookmark before B2.
+Return nil if neither sorts before the other.
+
+Two Info bookmarks are compared first by manual name, then by node
+name, then by position.
+
+If `bmkp-info-sort-ignores-directories-flag' is non-nil then manual
+names are used.  If it is nil then absolute file names for the manuals
+are used.
+
+True also if B1 is an Info bookmark but B2 is not.
+Reverse the roles of B1 and B2 for a false value.
+A true value is returned as `(t)', a false value as `(nil)'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+  (setq b1  (bmkp-get-bookmark b1)
+        b2  (bmkp-get-bookmark b2))
+  (let ((i1  (bmkp-info-bookmark-p b1))
+        (i2  (bmkp-info-bookmark-p b2))
+        (fn  (if bmkp-info-sort-ignores-directories-flag #'file-name-nondirectory #'abbreviate-file-name)))
+    (cond ((and i1 i2)
+           (setq i1  (funcall fn (bookmark-get-filename b1))
+                 i2  (funcall fn (bookmark-get-filename b2)))
+           (when case-fold-search (setq i1  (bmkp-upcase i1)
+                                        i2  (bmkp-upcase i2)))
+           (cond ((string-lessp i1 i2)                  '(t)) ; Compare manuals (file names).
+                 ((string-lessp i2 i1)                  '(nil))
+                 (t                     ; Compare node names.
+                  (setq i1  (bookmark-prop-get b1 'info-node)
+                        i2  (bookmark-prop-get b2 'info-node))
+                  (cond ((string-lessp i1 i2)           '(t))
+                        ((string-lessp i2 i1)           '(nil))
+                        (t
+                         (setq i1  (bookmark-get-position b1)
+                               i2  (bookmark-get-position b2))
+                         (cond ((or (not i1)  (not i2)) '(t)) ; Fallback if no `position' entry.
+                               ((<= i1 i2)              '(t))
+                               ((< i2 i1)               '(nil))))))))
+          (i1                                           '(t))
+          (i2                                           '(nil))
+          (t                                            nil))))
+
+(defun bmkp-info-position-cp (b1 b2)
+  "True if bookmark B1 sorts as Info bookmark before B2 in book order.
+Return nil if neither sorts before the other.
+
+Two Info bookmarks are compared first by manual name, then by position
+in the file.
+
+If `bmkp-info-sort-ignores-directories-flag' is non-nil then manual
+names are used.  If it is nil then absolute file names for the manuals
+are used.
+
+True also if B1 is an Info bookmark but B2 is not.
+Reverse the roles of B1 and B2 for a false value.
+A true value is returned as `(t)', a false value as `(nil)'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+  (setq b1  (bmkp-get-bookmark b1)
+        b2  (bmkp-get-bookmark b2))
+  (let ((i1  (bmkp-info-bookmark-p b1))
+        (i2  (bmkp-info-bookmark-p b2))
+        (fn  (if bmkp-info-sort-ignores-directories-flag #'file-name-nondirectory #'abbreviate-file-name)))
+    (cond ((and i1 i2)
+           (setq i1  (funcall fn (bookmark-get-filename b1))
+                 i2  (funcall fn (bookmark-get-filename b2)))
+           (when case-fold-search (setq i1  (bmkp-upcase i1)
+                                        i2  (bmkp-upcase i2)))
+           (cond ((string-lessp i1 i2)                  '(t)) ; Compare manuals (file names).
+                 ((string-lessp i2 i1)                  '(nil))
+                 (t                     ; Compare positions.
+                  (setq i1  (bookmark-get-position b1)
+                        i2  (bookmark-get-position b2))
+                  (cond ((or (not i1)  (not i2)) '(t)) ; Fallback if no `position' entry.
+                        ((<= i1 i2)              '(t))
+                        ((< i2 i1)               '(nil))))))
+          (i1                                           '(t))
+          (i2                                           '(nil))
+          (t                                            nil))))
+
+(defun bmkp-gnus-cp (b1 b2)
+  "True if bookmark B1 sorts as a Gnus bookmark before B2.
+Return nil if neither sorts before the other.
+
+Two Gnus bookmarks are compared first by Gnus group name, then by
+article number, then by message ID.
+True also if B1 is a Gnus bookmark but B2 is not.
+Reverse the roles of B1 and B2 for a false value.
+A true value is returned as `(t)', a false value as `(nil)'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+  (setq b1  (bmkp-get-bookmark b1)
+        b2  (bmkp-get-bookmark b2))
+  (let ((g1  (bmkp-gnus-bookmark-p b1))
+        (g2  (bmkp-gnus-bookmark-p b2)))
+    (cond ((and g1 g2)
+           (setq g1  (bookmark-prop-get b1 'group)
+                 g2  (bookmark-prop-get b2 'group))
+           (cond ((string-lessp g1 g2)                '(t)) ; Compare groups.
+                 ((string-lessp g2 g1)                '(nil))
+                 (t                     ; Compare article numbers.
+                  (setq g1  (bookmark-prop-get b1 'article)
+                        g2  (bookmark-prop-get b2 'article))
+                  (cond ((< g1 g2)                    '(t))
+                        ((< g2 g1)                    '(nil))
+                        (t
+                         (setq g1  (bookmark-prop-get b1 'message-id)
+                               g2  (bookmark-prop-get b2 'message-id))
+                         (cond ((string-lessp g1 g2)  '(t)) ; Compare message IDs.
+                               ((string-lessp g2 g1)  '(nil))
+                               (t                     nil)))))))
+          (g1                                         '(t))
+          (g2                                         '(nil))
+          (t                                          nil))))
+
+(defun bmkp-url-cp (b1 b2)
+  "True if bookmark B1 sorts as a URL bookmark before B2.
+Return nil if neither sorts before the other.
+
+Two URL bookmarks are compared alphabetically, by their URLs.
+True also if B1 is a URL bookmark but B2 is not.
+Reverse the roles of B1 and B2 for a false value.
+A true value is returned as `(t)', a false value as `(nil)'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+  (setq b1  (bmkp-get-bookmark b1)
+        b2  (bmkp-get-bookmark b2))
+  (let ((u1  (bmkp-url-bookmark-p b1))
+        (u2  (bmkp-url-bookmark-p b2)))
+    (cond ((and u1 u2)
+           (setq u1  (or (bookmark-prop-get b1 'location)  (bookmark-get-filename b1))
+                 u2  (or (bookmark-prop-get b2 'location)  (bookmark-get-filename b2)))
+           (cond ((string-lessp u1 u2)  '(t))
+                 ((string-lessp u2 u1)  '(nil))
+                 (t                     nil)))
+          (u1                           '(t))
+          (u2                           '(nil))
+          (t                            nil))))
+
+;; Not used now.
+(defun bmkp-w3m-cp (b1 b2)
+  "True if bookmark B1 sorts as a W3M URL bookmark before B2.
+Return nil if neither sorts before the other.
+
+Two W3M URL bookmarks are compared alphabetically, by their URLs.
+True also if B1 is a W3M bookmark but B2 is not.
+Reverse the roles of B1 and B2 for a false value.
+A true value is returned as `(t)', a false value as `(nil)'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+  (setq b1  (bmkp-get-bookmark b1)
+        b2  (bmkp-get-bookmark b2))
+  (let ((w1  (bmkp-w3m-bookmark-p b1))
+        (w2  (bmkp-w3m-bookmark-p b2)))
+    (cond ((and w1 w2)
+           (setq w1  (bookmark-get-filename b1)
+                 w2  (bookmark-get-filename b2))
+           (cond ((string-lessp w1 w2)  '(t))
+                 ((string-lessp w2 w1)  '(nil))
+                 (t                     nil)))
+          (w1                           '(t))
+          (w2                           '(nil))
+          (t                            nil))))
+
+(defun bmkp-position-cp (b1 b2)
+  "True if the `position' of B1 is not greater than that of B2.
+Return nil if B1 and B2 do not bookmark the same buffer or they have
+the same `position' value.
+
+Reverse the roles of B1 and B2 for a false value.
+A true value is returned as `(t)', a false value as `(nil)'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+  (setq b1  (bmkp-get-bookmark b1)
+        b2  (bmkp-get-bookmark b2))
+  (let ((buf1  (bmkp-get-buffer-name b1))
+        (buf2  (bmkp-get-buffer-name b2)))
+    (and buf1 buf2 (equal buf1 buf2)
+         (let ((i1  (bookmark-get-position b1))
+               (i2  (bookmark-get-position b2)))
+           (cond ((or (not i1)  (not i2)) '(t)) ; Fallback if no `position' entry.
+                 ((<= i1 i2)              '(t))
+                 ((< i2 i1)               '(nil)))))))
+
+(defun bmkp-alpha-cp (b1 b2)
+  "True if bookmark B1's name sorts alphabetically before B2's.
+Return nil if neither sorts before the other.
+
+The bookmark names are compared, respecting `case-fold-search'.
+Reverse the roles of B1 and B2 for a false value.
+A true value is returned as `(t)', a false value as `(nil)'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+  (setq b1  (bmkp-get-bookmark b1)
+        b2  (bmkp-get-bookmark b2))
+  (let ((s1  (car b1))
+        (s2  (car b2)))
+    (when case-fold-search (setq s1  (bmkp-upcase s1)
+                                 s2  (bmkp-upcase s2)))
+    (cond ((string-lessp s1 s2)  '(t))
+          ((string-lessp s2 s1)  '(nil))
+          (t                     nil))))
+
+;; Do not use `bmkp-make-plain-predicate', because it falls back on `bookmark-alpha-p'.
+;; Return nil if `bookmark-alpha-cp' cannot decide.
+(defun bmkp-alpha-p (b1 b2)
+  "True if bookmark B1's name sorts alphabetically before B2's.
+The bookmark names are compared, respecting `case-fold-search'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+  (setq b1  (bmkp-get-bookmark b1)
+        b2  (bmkp-get-bookmark b2))
+  (car (bmkp-alpha-cp b1 b2)))
+
+
+;;(@* "Sorting - File-Name Predicates")
+;;  *** Sorting - File-Name Predicates ***
+
+(defun bmkp-file-alpha-cp (b1 b2)
+  "True if bookmark B1's file name sorts alphabetically before B2's.
+Return nil if neither sorts before the other.
+
+The file names are shortened using `abbreviate-file-name', then they
+are compared respecting `case-fold-search'.
+
+Reverse the roles of B1 and B2 for a false value.
+A true value is returned as `(t)', a false value as `(nil)'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+  (setq b1  (bmkp-get-bookmark b1)
+        b2  (bmkp-get-bookmark b2))
+  (let ((f1  (bmkp-file-bookmark-p b1))
+        (f2  (bmkp-file-bookmark-p b2)))
+    (cond ((and f1 f2)
+           ;; Call `abbreviate-file-name' mainly to get letter case right per platform.
+           (setq f1  (abbreviate-file-name (bookmark-get-filename b1))
+                 f2  (abbreviate-file-name (bookmark-get-filename b2)))
+           (when case-fold-search (setq f1  (bmkp-upcase f1)
+                                        f2  (bmkp-upcase f2)))
+           (cond ((string-lessp f1 f2)  '(t))
+                 ((string-lessp f2 f1)  '(nil))
+                 (t                     nil)))
+          (f1                           '(t))
+          (f2                           '(nil))
+          (t                            nil))))
+
+;; We define all file-attribute predicates, in case you want to use them.
+;;
+;; `bmkp-file-attribute-0-cp'  - type
+;; `bmkp-file-attribute-1-cp'  - links
+;; `bmkp-file-attribute-2-cp'  - uid
+;; `bmkp-file-attribute-3-cp'  - gid
+;; `bmkp-file-attribute-4-cp'  - last access time
+;; `bmkp-file-attribute-5-cp'  - last update time
+;; `bmkp-file-attribute-6-cp'  - last status change
+;; `bmkp-file-attribute-7-cp'  - size
+;; `bmkp-file-attribute-8-cp'  - modes
+;; `bmkp-file-attribute-9-cp'  - gid change
+;; `bmkp-file-attribute-10-cp' - inode
+;; `bmkp-file-attribute-11-cp' - device
+;;
+(bmkp-define-file-sort-predicate 0) ; Type: file, symlink, dir
+(bmkp-define-file-sort-predicate 1) ; Links
+(bmkp-define-file-sort-predicate 2) ; Uid
+(bmkp-define-file-sort-predicate 3) ; Gid
+(bmkp-define-file-sort-predicate 4) ; Last access time
+(bmkp-define-file-sort-predicate 5) ; Last modification time
+(bmkp-define-file-sort-predicate 6) ; Last status-change time
+(bmkp-define-file-sort-predicate 7) ; Size
+(bmkp-define-file-sort-predicate 8) ; Modes
+(bmkp-define-file-sort-predicate 9) ; Gid would change if re-created
+(bmkp-define-file-sort-predicate 10) ; Inode
+(bmkp-define-file-sort-predicate 11) ; Device
+
+(defun bmkp-local-file-accessed-more-recently-cp (b1 b2)
+  "True if bookmark B1's local file was accessed more recently than B2's.
+Return nil if neither sorts before the other.
+
+A local file sorts before a remote file, which sorts before other
+bookmarks.  Two remote files are considered incomparable - their
+access times are not examined.
+
+Reverse the roles of B1 and B2 for a false value.
+A true value is returned as `(t)', a false value as `(nil)'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+  (setq b1  (bmkp-get-bookmark b1)
+        b2  (bmkp-get-bookmark b2))
+  (cond ((and (bmkp-local-file-bookmark-p b1)  (bmkp-local-file-bookmark-p b2))
+         (bmkp-cp-not (bmkp-file-attribute-4-cp b1 b2)))
+        ((bmkp-local-file-bookmark-p b1)         '(t))
+        ((bmkp-local-file-bookmark-p b2)         '(nil))
+        ((and (bmkp-remote-file-bookmark-p b1)
+              (bmkp-remote-file-bookmark-p b2))  nil)
+        ((bmkp-remote-file-bookmark-p b1)        '(t))
+        ((bmkp-remote-file-bookmark-p b2)        '(nil))
+        (t                                       nil)))
+
+(defun bmkp-local-file-updated-more-recently-cp (b1 b2)
+  "True if bookmark B1's local file was updated more recently than B2's.
+Return nil if neither sorts before the other.
+
+A local file sorts before a remote file, which sorts before other
+bookmarks.  Two remote files are considered incomparable - their
+update times are not examined.
+
+Reverse the roles of B1 and B2 for a false value.
+A true value is returned as `(t)', a false value as `(nil)'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+  (setq b1  (bmkp-get-bookmark b1)
+        b2  (bmkp-get-bookmark b2))
+  (cond ((and (bmkp-local-file-bookmark-p b1)  (bmkp-local-file-bookmark-p b2))
+         (bmkp-cp-not (bmkp-file-attribute-5-cp b1 b2)))
+        ((bmkp-local-file-bookmark-p b1)         '(t))
+        ((bmkp-local-file-bookmark-p b2)         '(nil))
+        ((and (bmkp-remote-file-bookmark-p b1)
+              (bmkp-remote-file-bookmark-p b2))  nil)
+        ((bmkp-remote-file-bookmark-p b1)        '(t))
+        ((bmkp-remote-file-bookmark-p b2)        '(nil))
+        (t                                       nil)))
+
+(defun bmkp-local-file-size-cp (b1 b2)
+  "True if bookmark B1's local file is larger than B2's.
+Return nil if neither sorts before the other.
+
+A local file sorts before a remote file, which sorts before other
+bookmarks.  Two remote files are considered incomparable - their
+sizes are not examined.
+
+Reverse the roles of B1 and B2 for a false value.
+A true value is returned as `(t)', a false value as `(nil)'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+  (setq b1  (bmkp-get-bookmark b1)
+        b2  (bmkp-get-bookmark b2))
+  (cond ((and (bmkp-local-file-bookmark-p b1)  (bmkp-local-file-bookmark-p b2))
+         (bmkp-cp-not (bmkp-file-attribute-7-cp b1 b2)))
+        ((bmkp-local-file-bookmark-p b1)         '(t))
+        ((bmkp-local-file-bookmark-p b2)         '(nil))
+        ((and (bmkp-remote-file-bookmark-p b1)
+              (bmkp-remote-file-bookmark-p b2))  nil)
+        ((bmkp-remote-file-bookmark-p b1)        '(t))
+        ((bmkp-remote-file-bookmark-p b2)        '(nil))
+        (t                                       nil)))
+
+(defun bmkp-local-file-type-cp (b1 b2)
+  "True if bookmark B1 sorts by local file type before B2.
+Return nil if neither sorts before the other.
+
+For two local files, a file sorts before a symlink, which sorts before
+a directory.
+
+A local file sorts before a remote file, which sorts before other
+bookmarks.  Two remote files are considered incomparable - their file
+types are not examined.
+
+Reverse the roles of B1 and B2 for a false value.
+A true value is returned as `(t)', a false value as `(nil)'.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+  (setq b1  (bmkp-get-bookmark b1)
+        b2  (bmkp-get-bookmark b2))
+  (cond ((and (bmkp-local-file-bookmark-p b1)  (bmkp-local-file-bookmark-p b2))
+         (bmkp-file-attribute-0-cp b1 b2))
+        ((bmkp-local-file-bookmark-p b1)         '(t))
+        ((bmkp-local-file-bookmark-p b2)         '(nil))
+        ((and (bmkp-remote-file-bookmark-p b1)
+              (bmkp-remote-file-bookmark-p b2))  nil)
+        ((bmkp-remote-file-bookmark-p b1)        '(t))
+        ((bmkp-remote-file-bookmark-p b2)        '(nil))
+        (t                                       nil)))
+
+(defun bmkp-cp-not (truth)
+  "Return the negation of boolean value TRUTH.
+If TRUTH is (t), return (nil), and vice versa.
+If TRUTH is nil, return nil."
+  (and truth  (if (car truth) '(nil) '(t))))
+
+
+;;(@* "Indirect Bookmarking Functions")
+;;  *** Indirect Bookmarking Functions ***
+
+;;;###autoload (autoload 'bmkp-url-target-set "bookmark+")
+(defun bmkp-url-target-set (url &optional arg name/prefix no-overwrite-p no-refresh-p msg-p)
+                                        ; Bound globally to `C-x x c u'.
+  "Set a bookmark for a URL.  Return the bookmark.
+Interactively you are prompted for the URL.  Completion is available.
+Use `M-n' to pick up the url at point as the default.
+
+You are also prompted for the bookmark name.  But with a non-negative
+prefix arg, you are prompted only for a bookmark-name prefix.  In that
+case, the bookmark name is the prefix followed by the URL.
+
+When entering a bookmark name you can use completion against existing
+names.  This completion is lax, so you can easily edit an existing
+name.  See `bookmark-set' for particular keys available during this
+input.
+
+If you use a numeric prefix arg, such as `C-1', instead of plain
+`C-u', then a new bookmark is created if a bookmark of the same name
+already exists: an existing bookmark is not overwritten.  You can thus
+have multiple bookmarks with the same name, which target different
+URLs.
+
+Summary of prefix argument behavior:
+
+* None:        Provide full bookmark name. Overwrite existing bookmark
+* Plain `C-u': Provide name prefix only.   Overwrite existing bookmark
+* N >= 0:      Provide name prefix only.   Do not overwrite.
+* N < 0:       Provide full bookmark name. Do not overwrite.
+
+Non-interactively:
+* Numeric ARG >= 0 means NAME/PREFIX is a bookmark-name prefix.
+* NAME/PREFIX is the bookmark name or its prefix (the suffix = URL).
+* Non-nil NO-OVERWRITE-P means do not overwrite an existing bookmark.
+* Non-nil NO-REFRESH-P means do not refresh/rebuild the bookmark-list
+  display.
+* Non-nil MSG-P means display a status message."
+  (interactive
+   (let* ((icicle-unpropertize-completion-result-flag  t)
+          (default-url                                 (or (bmkp-thing-at-point 'url)
+                                                           (and (fboundp 'url-get-url-at-point)
+                                                                (url-get-url-at-point))
+                                                           ;; TEMPORARY hack to work around Emacs bug #44822.
+                                                           "https://example.com"))
+          (parg                                        current-prefix-arg)
+          (prefix-only                                 (and parg  (natnump (prefix-numeric-value parg))))
+          (no-overw                                    (and parg  (atom current-prefix-arg))))
+     (list (if (require 'ffap nil t)
+               (ffap-read-file-or-url "URL: " default-url)
+             (read-from-minibuffer "URL: " nil nil nil nil default-url))
+           prefix-only
+           (if prefix-only
+               (read-string "Prefix for bookmark name: ")
+             (bmkp-completing-read-lax "Bookmark name"))
+           no-overw
+           nil
+           'MSG)))
+  (unless name/prefix (setq name/prefix  ""))
+  (let ((bookmark-make-record-function  (cond ((and (eq major-mode 'eww-mode)
+                                                    (fboundp 'bmkp-make-eww-record)) ; Emacs 25+
+                                               'bmkp-make-eww-record)
+                                              ((eq major-mode 'w3m-mode) 'bmkp-make-w3m-record)
+                                              (t `(lambda () (bmkp-make-url-browse-record ',url)))))
+        bmk failure)
+    (condition-case err
+        (setq bmk  (bookmark-store (if arg (concat name/prefix url) name/prefix)
+                                   (cdr (bookmark-make-record))  no-overwrite-p  no-refresh-p  (not msg-p)))
+      (error (setq failure  err)))
+    (when failure (error "Failed to create bookmark for `%s':\n%s\n" url failure))
+    bmk))                               ; Return the bookmark.
+
+;;;###autoload (autoload 'bmkp-file-target-set "bookmark+")
+(defun bmkp-file-target-set (file &optional arg name/prefix no-overwrite no-refresh-p msg-p)
+                                        ; Bound to `C-x x c f'
+  "Set a bookmark for FILE.  Return the bookmark.
+The bookmarked position is the beginning of the file (0).
+Interactively you are prompted for FILE.  Completion is available.
+You can use `M-n' to pick up the file name at point, or if none then
+the visited file.
+
+FILE can also be a directory name.  In that case set a bookmark for
+the directory.
+
+You are also prompted for the bookmark name.  But with a non-negative
+prefix arg, you are prompted only for a bookmark-name prefix.  In that
+case, the bookmark name is the prefix followed by the nondirectory
+part of FILE (or of its `directory-file-name', if a directory name).
+
+When entering a bookmark name you can use completion against existing
+names.  This completion is lax, so you can easily edit an existing
+name.  See `bookmark-set' for particular keys available during this
+input.
+
+If you use a numeric prefix arg, such as `C-1', instead of plain
+`C-u', then a new bookmark is created if a bookmark of the same name
+already exists: an existing bookmark is not overwritten.  You can thus
+have multiple bookmarks with the same name, which target different
+URLs.
+
+Summary of prefix argument behavior:
+
+* None:        Provide full bookmark name. Overwrite existing bookmark
+* Plain `C-u': Provide name prefix only.   Overwrite existing bookmark
+* N >= 0:      Provide name prefix only.   Do not overwrite.
+* N < 0:       Provide full bookmark name  Do not overwrite.
+
+Non-interactively:
+* Numeric ARG >= 0 means NAME/PREFIX is a bookmark-name prefix.
+* NAME/PREFIX is the bookmark name or its prefix.
+* Non-nil NO-OVERWRITE-P means do not overwrite an existing bookmark.
+* Non-nil NO-REFRESH-P means do not refresh/rebuild the bookmark-list
+  display.
+* Non-nil MSG-P means show a warning message if file does not exist."
+  (interactive
+   (let* ((icicle-unpropertize-completion-result-flag  t)
+          (parg                                        current-prefix-arg)
+          (prefix-only                                 (and parg  (natnump (prefix-numeric-value parg))))
+          (no-overw                                    (and parg  (atom current-prefix-arg))))
+     (list (read-file-name "File: " nil
+                           (or (if (boundp 'file-name-at-point-functions) ; In `files.el', Emacs 23.2+.
+                                   (run-hook-with-args-until-success 'file-name-at-point-functions)
+                                 (bmkp-ffap-guesser))
+                               (bmkp-thing-at-point 'filename)
+                               (buffer-file-name)))
+           prefix-only
+           (if prefix-only
+               (read-string "Prefix for bookmark name: ")
+             (bmkp-completing-read-lax "Bookmark name"))
+           no-overw
+           nil
+           'MSG)))
+  (unless name/prefix (setq name/prefix  ""))
+  (let ((bookmark-make-record-function  (bmkp-make-record-for-target-file file))
+        bmk failure)
+    (condition-case err
+        (setq bmk  (bookmark-store (if arg
+                                       (concat name/prefix
+                                               (file-name-nondirectory (if (file-directory-p file)
+                                                                           (directory-file-name file)
+                                                                         file)))
+                                     name/prefix)
+                                   (cdr (bookmark-make-record))  no-overwrite  no-refresh-p  (not msg-p)))
+      (error (setq failure  (error-message-string err))))
+    (when failure (error "Failed to create bookmark for `%s':\n%s\n" file failure))
+    (unless no-refresh-p (bmkp-refresh/rebuild-menu-list bmk (not msg-p)))
+    (when (and msg-p  (not (file-exists-p file)))
+      (message "File name is now bookmarked, but no such file yet: `%s'" (expand-file-name file)))
+    bmk))                               ; Return the bookmark.
+
+(defun bmkp-make-record-for-target-file (file)
+  "Return a function that creates a bookmark record for FILE.
+The bookmarked position will be the beginning of the file."
+  ;; $$$$$$ Maybe need a way to bypass default handler, at least for autofiles.
+  ;;        Doesn't seem to make much sense to use a handler such as a shell cmd in this context. (?)
+  (set-text-properties 0 (length file) () file)
+  (let ((default-handler  (condition-case nil (bmkp-default-handler-for-file file) (error nil)))
+        (common           `((filename     . ,file)
+                            (position     . 0)
+                            (created      . ,(current-time)))))
+    (cond (default-handler              ; User default handler
+              `(lambda () ',(append common `((file-handler . ,default-handler)))))
+          ;; Non-user defaults.
+          ((and (require 'image nil t)  (require 'image-mode nil t) ; Image
+                (condition-case nil (image-type file) (error nil)))
+           ;; Last two lines of function are from `image-bookmark-make-record'.
+           ;; But don't use that directly, because it uses
+           ;; `bookmark-make-record-default', which gets nil for `filename'.
+
+           ;; NEED TO KEEP THIS CODE SYNC'D WITH `diredp-bookmark'.
+           `(lambda ()
+             ',(append common `((image-type . ,(image-type file)) (handler . image-bookmark-jump)))))
+          ((let ((case-fold-search  t))  (bmkp-string-match-p "\\([.]au$\\|[.]wav$\\)" file)) ; Sound
+           ;; Obsolete: `(lambda () '((filename . ,file) (handler . bmkp-sound-jump))))
+           `(lambda () ',(append common '((file-handler . play-sound-file)))))
+          (t
+           `(lambda () ',common)))))
+
+(when (fboundp 'file-cache-add-file)
+  (defadvice file-cache-add-file (around bmkp-autofile-filecache activate)
+    "Respect option `bmkp-autofile-filecache'."
+    (cond ((eq bmkp-autofile-filecache  'autofile-only)
+           (bmkp-autofile-set
+            (ad-get-arg 0) nil nil
+            'NO-REFRESH-P))
+          ((eq bmkp-autofile-filecache  'autofile+cache)
+           (progn
+             ad-do-it
+             (bmkp-autofile-set
+              (ad-get-arg 0) nil nil
+              'NO-REFRESH-P 'MSG-P)))
+          ((eq bmkp-autofile-filecache  'cache-only)
+           ad-do-it))))
+
+(defun bmkp-find-file-invoke-bookmark-if-autofile ()
+  "Invoke the autofile bookmark associated with the visited file.
+This is added to `find-file-hook' when option
+`bmkp-autofile-access-invokes-bookmark-flag' is non-nil.  When invoked
+it causes regular file access to invoke the associated bookmark.  This
+has the effect of updating the bookmark data, such as the number of
+visits."
+  (let* ((buf-file  (buffer-file-name))
+         (bmk       (bmkp-get-bookmark-in-alist (file-name-nondirectory buf-file)
+                                                t
+                                                (bmkp-autofile-alist-only)))
+         (bmk-file  (and bmk  (bookmark-get-filename bmk))))
+    (when (and bmk-file  (bmkp-same-file-p buf-file bmk-file))
+      (let ((bmkp-autofile-access-invokes-bookmark-flag  nil)) ; Just to be sure.
+        (bookmark--jump-via bmk 'ignore)))))
+
+;;;###autoload (autoload 'bmkp-bookmark-a-file "bookmark+")
+(defalias 'bmkp-bookmark-a-file 'bmkp-autofile-set)
+;;;###autoload (autoload 'bmkp-autofile-set "bookmark+")
+(defun bmkp-autofile-set (file &optional dir prefix no-refresh-p msg-p) ; Bound to `C-x x c a'
+  "Set a bookmark for FILE, autonaming the bookmark for the file.
+Return the bookmark.
+Interactively, you are prompted for FILE.  You can use `M-n' to pick
+up the file name at point or the visited file.
+
+The bookmark name is the nondirectory part of FILE, but with a prefix
+arg you are also prompted for a PREFIX string to prepend to the
+bookmark name.  The bookmarked position is the beginning of the file.
+
+Note that if you provide PREFIX then the bookmark will not satisfy
+`bmkp-autofile-bookmark-p' unless you provide the same PREFIX to that
+predicate.
+
+The bookmark's file name is FILE if absolute.  If relative then it is
+FILE expanded in DIR, if non-nil, or in the current directory
+\(`default-directory').
+
+If a bookmark with the same name already exists for the same file name
+then do nothing.
+
+Otherwise, create a new bookmark for the file, even if a bookmark with
+the same name already exists.  This means that you can have more than
+one autofile bookmark with the same bookmark name and the same
+relative file name (nondirectory part), but with different absolute
+file names.
+
+Non-interactively:
+ - Non-nil NO-REFRESH-P means do not refresh/rebuild the bookmark-list
+   display.
+ - Non-nil optional arg MSG-P means display status messages."
+  (interactive
+   (list (let ((icicle-unpropertize-completion-result-flag  t))
+           (read-file-name "File: " nil
+                           (if (or (> emacs-major-version 23)
+                                   (and (= emacs-major-version 23)  (> emacs-minor-version 1)))
+                               (let ((deflts  ())
+                                     def)
+                                 (when (setq def  (buffer-file-name)) (push def deflts))
+                                 (when (setq def  (bmkp-thing-at-point 'filename)) (push def deflts))
+                                 (when (setq def  (bmkp-ffap-guesser)) (push def deflts))
+                                 (when (and (boundp 'file-name-at-point-functions)
+                                            (setq def  (run-hook-with-args-until-success
+                                                        'file-name-at-point-functions)))
+                                   (push def deflts))
+                                 deflts)
+                             (or (if (boundp 'file-name-at-point-functions) ; In `files.el', Emacs 23.2+.
+                                     (run-hook-with-args-until-success 'file-name-at-point-functions)
+                                   (bmkp-ffap-guesser))
+                                 (bmkp-thing-at-point 'filename)
+                                 (buffer-file-name)))))
+         nil
+         (and current-prefix-arg  (read-string "Prefix for bookmark name: "))
+         nil
+         'MSG))
+  (let* ((dir-to-use  (if (file-name-absolute-p file)
+                          (file-name-directory file)
+                        (or dir  default-directory)))
+         ;; Look for existing bookmark with same name, same file, in `dir-to-use'.
+         (bmk         (bmkp-get-autofile-bookmark file dir-to-use prefix)))
+    ;; If BMK was found, then instead of doing nothing we could replace the existing BMK with a new
+    ;; one, as follows:
+    ;; (let ((bookmark-make-record-function (bmkp-make-record-for-target-file file)))
+    ;;   (bmkp-replace-existing-bookmark bmk)) ; Update the existing bookmark.
+    (if (not bmk)
+        ;; Create a new bookmark, and return it.
+        (bmkp-file-target-set (expand-file-name file dir-to-use) t prefix 'NO-OVERWRITE no-refresh-p msg-p)
+      (when msg-p (message "Autofile bookmark set for `%s'" file))
+      bmk)))                            ; Return the bookmark.
+
+(defun bmkp-get-autofile-bookmark (file &optional dir prefix)
+  "Return an existing autofile bookmark for FILE, or nil if there is none.
+The bookmark name is PREFIX prepended to the nondirectory part of
+FILE (or of FILE's `directory-file-name', if FILE is a directory).
+
+If PREFIX is nil then it acts like an empty prefix (\"\").
+
+The directory part of bookmark entry `filename' is the directory part
+of FILE, if FILE is absolute.  Otherwise, it is DIR, if non-nil, or
+`default-directory' otherwise.
+
+FILE and the `filename' entry of the bookmark returned are the same,
+except possibly for their directory parts (see previous)."
+  (let* ((fname       (file-name-nondirectory (if (file-directory-p file)
+                                                  (directory-file-name file)
+                                                file)))
+         (bname       (if prefix (concat prefix fname) fname))
+         (dir-to-use  (if (file-name-absolute-p file)
+                          (file-name-directory file)
+                        (or dir  default-directory))))
+    ;; Look for existing bookmark with same name, same file, in `dir-to-use'.
+    (catch 'bmkp-get-autofile-bookmark
+      (dolist (bmk  bookmark-alist)
+        (when (string= bname (bmkp-bookmark-name-from-record bmk))
+          (let* ((bfil  (bookmark-get-filename bmk))
+                 (bdir  (and bfil  (file-name-directory bfil))))
+            (when (and bfil  bdir  (bmkp-same-file-p bdir  dir-to-use)  (bmkp-same-file-p bfil file))
+              (throw 'bmkp-get-autofile-bookmark bmk))))) ; Return the bookmark.
+      nil)))
+
+;;;###autoload (autoload 'bmkp-tag-a-file "bookmark+")
+(defalias 'bmkp-tag-a-file 'bmkp-autofile-add-tags) ; Bound to `C-x x t + a'
+;;;###autoload (autoload 'bmkp-autofile-add-tags "bookmark+")
+(defun bmkp-autofile-add-tags (file tags &optional dir prefix no-update-p msg-p)
+  "Add TAGS to the autofile bookmark for FILE (a file or directory name).
+Return the number of tags added.
+
+If there is no autofile bookmark for FILE, create one.
+Interactively, you are prompted for FILE and then TAGS.
+When prompted for FILE you can use `M-n' to pick up the file name at
+point, or if none then the visited file.
+
+With a non-negative prefix argument, you are prompted for a file-name
+prefix, as in `bmkp-autofile-set'.
+
+When prompted for tags, hit `RET' to enter each tag, then hit `RET'
+again after the last tag.  You can use completion to enter each tag.
+Completion is lax: you are not limited to existing tags.
+
+By default, the tag choices for completion are NOT refreshed, to save
+time.  Use a non-positive prefix argument if you want to refresh them.
+
+Non-interactively:
+ - TAGS is a list of strings.
+ - DIR and PREFIX are as for `bmkp-autofile-set'.
+ - Non-nil NO-UPDATE-P means do not update `bmkp-tags-alist', do not
+   update the modification count and maybe save bookmarks, and do not
+   refresh/rebuild the bookmark-list display
+ - Non-nil MSG-P means display a message about the addition."
+  (interactive
+   (list (let ((icicle-unpropertize-completion-result-flag  t))
+           (read-file-name "File or directory to tag: " nil
+                           (or (if (boundp 'file-name-at-point-functions) ; In `files.el', Emacs 23.2+.
+                                   (run-hook-with-args-until-success 'file-name-at-point-functions)
+                                 (bmkp-ffap-guesser))
+                               (bmkp-thing-at-point 'filename)
+                               (buffer-file-name))))
+         (bmkp-read-tags-completing nil nil (and current-prefix-arg
+                                                 (<= (prefix-numeric-value current-prefix-arg) 0)))
+         nil
+         (and current-prefix-arg  (wholenump (prefix-numeric-value current-prefix-arg))
+              (read-string "Prefix for bookmark name: "))
+         nil
+         'MSG))
+  (bmkp-add-tags (bmkp-autofile-set file dir prefix no-update-p) tags no-update-p msg-p))
+
+;;;###autoload (autoload 'bmkp-untag-a-file "bookmark+")
+(defalias 'bmkp-untag-a-file 'bmkp-autofile-remove-tags) ; Bound to `C-x x t - a'
+;;;###autoload (autoload 'bmkp-autofile-remove-tags "bookmark+")
+(defun bmkp-autofile-remove-tags (file tags &optional dir prefix no-update-p msg-p)
+  "Remove TAGS from autofile bookmark for FILE.
+Return the number of tags removed.
+
+Interactively, you are prompted for TAGS and then FILE.
+With Emacs 22 and later, only files with at least one of the given
+tags are candidates.
+
+When prompted for FILE you can use `M-n' to pick up the file name at
+point, or if none then the visited file.
+
+With a non-negative prefix argument, you are prompted for a file-name
+prefix, as in `bmkp-autofile-set'.
+
+
+When prompted for tags, hit `RET' to enter each tag to be removed,
+then hit `RET' again after the last tag.  You can use completion to
+enter each tag.
+
+By default, the tag choices for completion are NOT refreshed, to save
+time.  Use a non-positive prefix argument if you want to refresh them.
+
+Non-interactively:
+ - TAGS is a list of strings.
+ - DIR and PREFIX are as for `bmkp-autofile-set'.
+ - Non-nil NO-UPDATE-P means do not update `bmkp-tags-alist', do not
+   update the modification count and maybe save bookmarks, and do not
+   refresh/rebuild the bookmark-list display
+ - Non-nil MSG-P means display a message about the removal."
+  (interactive
+   (lexical-let* ((pref
+                   (and current-prefix-arg  (wholenump (prefix-numeric-value current-prefix-arg))
+                        (read-string "Prefix for bookmark name: ")))
+                  (tgs
+                   (bmkp-read-tags-completing nil nil (and current-prefix-arg
+                                                           (<= (prefix-numeric-value current-prefix-arg) 0))))
+                  (icicle-unpropertize-completion-result-flag  t) ; For `read-file-name'.
+                  (fil   (condition-case nil
+                             (read-file-name
+                              "File: " nil
+                              (or (if (boundp 'file-name-at-point-functions) ; In `files.el', Emacs 23.2+.
+                                      (run-hook-with-args-until-success 'file-name-at-point-functions)
+                                    (bmkp-ffap-guesser))
+                                  (bmkp-thing-at-point 'filename)
+                                  (buffer-file-name))
+                              t nil (lambda (ff) ; PREDICATE - only for Emacs 22+.
+                                      (let* ((bmk   (bmkp-get-autofile-bookmark ff nil pref))
+                                             (btgs  (and bmk  (bmkp-get-tags bmk))))
+                                        (and btgs  (catch 'bmkp-autofile-remove-tags-pred
+                                                     (dolist (tag  tgs)
+                                                       (when (not (member tag btgs))
+                                                         (throw 'bmkp-autofile-remove-tags-pred nil)))
+                                                     t)))))
+                           (error (read-file-name "File: " nil (or (bmkp-ffap-guesser)
+                                                                   (bmkp-thing-at-point 'filename)
+                                                                   (buffer-file-name)))))))
+     (list fil tgs nil pref nil 'MSG)))
+  (bmkp-remove-tags (bmkp-autofile-set file dir prefix no-update-p) tags no-update-p msg-p))
+
+;;;###autoload (autoload 'bmkp-purge-notags-autofiles "bookmark+")
+(defun bmkp-purge-notags-autofiles (&optional prefix msg-p) ; Not bound
+  "Delete all autofile bookmarks that have no tags.
+With a prefix arg, you are prompted for a PREFIX for the bookmark name.
+Non-interactively, non-nil MSG-P means display a status message."
+  (interactive (if (not (y-or-n-p "Delete all autofile bookmarks that do not have tags? "))
+                   (error "OK - deletion canceled")
+                 (list (and current-prefix-arg  (read-string "Prefix for bookmark name: ")) 'MSG)))
+  (let ((bmks                (bmkp-autofile-alist-only prefix))
+        (bookmark-save-flag  (and (not bmkp-count-multi-mods-as-one-flag)
+                                  bookmark-save-flag)) ; Save only after `dolist'.
+        record tags)
+    ;; Needs Bookmark+ version of `bookmark-delete', which accepts a bookmark, not just its name.
+    (dolist (bmk  bmks)
+      (when (and (setq tags  (assq 'tags (bmkp-bookmark-data-from-record bmk)))
+                 (or (not tags)  (null (cdr tags))))
+        (bookmark-delete bmk 'BATCHP)))) ; Do not refresh list here - do it after iterate.
+  (bmkp-tags-list)                      ; Update the tags cache now, after iterate.
+  (bmkp-maybe-save-bookmarks)           ; Increments `bookmark-alist-modification-count'.
+  (bmkp-refresh/rebuild-menu-list nil (not msg-p))) ; Refresh now, after iterate.
+
+
+;; $$$$$$ Not used currently.
+(defun bmkp-replace-existing-bookmark (bookmark)
+  "Replace existing BOOKMARK with a new one of the same name.
+Return the new bookmark.
+BOOKMARK is a full bookmark record, not a bookmark name.
+
+This replaces the existing bookmark data with the data for a new
+bookmark, based on `bookmark-make-record-function'.  It also updates
+the `bmkp-full-record' on the bookmark name (without otherwise
+changing the name)."
+  (let (failure)
+    (condition-case err
+        (progn                          ; Code similar to `bookmark-store'.
+          (setcdr bookmark (cdr (bookmark-make-record)))
+          (bmkp-maybe-save-bookmarks)
+          ;; Put the full bookmark on its name as property `bmkp-full-record'.
+          ;; Do this regardless of Emacs version and `bmkp-propertize-bookmark-names-flag'.
+          ;; If it needs to be stripped, that will be done when saving.
+          (let ((bname  (bmkp-bookmark-name-from-record bookmark)))
+            (put-text-property 0 (length bname) 'bmkp-full-record bookmark bname)
+            ;; This is the same as `add-to-list' with `EQ' (not available for Emacs 20-21).
+            (unless (memq bookmark bmkp-modified-bookmarks)
+              (setq bmkp-modified-bookmarks  (cons bookmark bmkp-modified-bookmarks)))
+            (setq bookmark-current-bookmark  bname))
+          (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P))
+      (error (setq failure  (error-message-string err))))
+    (if (not failure)
+        bookmark                        ; Return the bookmark.
+      (error "Failed to update bookmark `%s':\n%s\n"
+             (bmkp-bookmark-name-from-record bookmark) failure))))
+
+(defun bmkp-default-handler-for-file (filename)
+  "Return a default bookmark handler for FILENAME, or nil.
+If non-nil, it is a Lisp function, determined as follows:
+
+1. Match FILENAME against `bmkp-default-handlers-for-file-types'.  If
+it matches a Lisp function, return that function.  If it matches a
+shell command, return a Lisp function that invokes that shell command.
+
+2. If no match is found and `bmkp-guess-default-handler-for-file-flag'
+is non-nil, then try to find an appropriate shell command using, in
+order, `dired-guess-default' and `mailcap-file-default-commands'
+\(Emacs 23+ only).  If a match is found then return a Lisp function
+that invokes that shell command."
+  (let* ((bmkp-user  (bmkp-default-handler-user filename))
+         (shell-cmd  (if (stringp bmkp-user)
+                         bmkp-user
+                       (and (not bmkp-user)
+                            bmkp-guess-default-handler-for-file-flag
+                            (or (and (require 'dired-x nil t)
+                                     (let* ((case-fold-search
+                                             (or (and (boundp 'dired-guess-shell-case-fold-search)
+                                                      dired-guess-shell-case-fold-search)
+                                                 case-fold-search))
+                                            (default  (dired-guess-default (list filename))))
+                                       (if (consp default) (car default) default)))
+                                (and (require 'mailcap nil t) ; Emacs 23+
+                                     (car (mailcap-file-default-commands (list filename)))))))))
+    (cond ((stringp shell-cmd) `(lambda (bmk) (dired-do-shell-command ',shell-cmd nil ',(list filename))))
+          ((or (functionp bmkp-user)  (and bmkp-user  (symbolp bmkp-user)))
+           bmkp-user)
+          (t nil))))
+
+(defun bmkp-default-handler-user (filename)
+  "Return default handler for FILENAME.
+The value is based on `bmkp-default-handlers-for-file-types'."
+  (catch 'bmkp-default-handler-user
+    (dolist (assn  bmkp-default-handlers-for-file-types)
+      (when (bmkp-string-match-p (car assn) filename) (throw 'bmkp-default-handler-user (cdr assn))))
+    nil))
+
+;; Keep this only for compatibility with existing bookmarks that have `bmkp-sound-jump' as `handler' prop.
+(defun bmkp-sound-jump (bookmark)
+  "Handler for sound files: play the sound file that is BOOKMARK's file.
+This is deprecated.  It is kept only for old bookmarks that already
+use this as the `handler' entry.  New sound bookmarks use
+`play-sound-file' as entry `file-handler'."
+  (play-sound-file (bookmark-get-filename bookmark)))
+
+(when (> emacs-major-version 21)
+  (defun bmkp-compilation-target-set (&optional prefix) ; Bound to `C-c C-b' in compilation mode
+    "Set a bookmark at the start of the line for this compilation hit.
+The bookmark is set in the indicated file at the indicated line.
+You are prompted for the bookmark name.  But with a prefix arg, you
+are prompted only for a PREFIX string.  In that case, and in Lisp
+code, the bookmark name is PREFIX followed by the (relative) file name
+of the hit, followed by the line number of the hit."
+    (interactive "P")
+    (let* ((file+line  (bmkp-compilation-file+line-at (line-beginning-position)))
+           (file       (car file+line))
+           (line       (cdr file+line)))
+      (unless (and file  line)  (error "Cursor is not on a compilation hit"))
+      (save-excursion
+        (with-current-buffer (let ((enable-local-variables  ())) (find-file-noselect file))
+          (goto-char (point-min)) (forward-line (1- line))
+          (if (not prefix)
+              (call-interactively #'bookmark-set)
+            (when (interactive-p)
+              (setq prefix  (read-string "Prefix for bookmark name: ")))
+            (unless (stringp prefix) (setq prefix  ""))
+            (bookmark-set (format "%s%s, line %s" prefix (file-name-nondirectory file) line)
+                          99 'INTERACTIVEP))))))
+
+  (defun bmkp-compilation-file+line-at (&optional pos)
+    "Return the file and position indicated by this compilation message.
+These are returned as a cons: (FILE . POSITION).
+POSITION is the beginning of the line indicated by the message."
+    (unless pos (setq pos  (point)))
+    (let* ((loc        (car (get-text-property pos 'message)))
+           (line       (cadr loc))
+           (filename   (caar (nth 2 loc)))
+           (directory  (cadr (car (nth 2 loc))))
+           (spec-dir   (if directory (expand-file-name directory) default-directory)))
+      (cons (expand-file-name filename spec-dir) line))))
+
+(when (> emacs-major-version 21)
+  (defun bmkp-compilation-target-set-all (prefix &optional msg-p) ; Bound to `C-c C-M-b' in compilation mode
+    "Set a bookmark for each hit of a compilation buffer.
+NOTE: You can use `C-x C-q' to make the buffer writable and then
+      remove any hits that you do not want to bookmark.  Only the hits
+      remaining in the buffer are bookmarked.
+
+Interactively, you are prompted for a PREFIX string to prepend to each
+bookmark name, the rest of which is the file name of the hit followed
+by its line number.
+Non-interactively, non-nil optional arg MSG-P means prompt and display
+status messages."
+    (interactive (list (read-string "Prefix for bookmark name: ") 'MSG))
+    (when (and msg-p  (not (y-or-n-p "This will bookmark *EACH* hit in the buffer.  Continue? ")))
+      (error "OK - canceled"))
+    (let ((count  0))
+      (save-excursion
+        (goto-char (point-min))
+        (when (get-text-property (point) 'message) ; Visible part of buffer starts with a hit
+          (condition-case nil           ; because buffer is narrowed or header text otherwise removed.
+              (bmkp-compilation-target-set prefix) ; Ignore error here (e.g. killed buffer).
+            (error nil))
+          (setq count  (1+ count)))
+        (while (and (condition-case nil (progn (compilation-next-error 1) t) (error nil))
+                    (not (eobp)))
+          (condition-case nil
+              (bmkp-compilation-target-set prefix) ; Ignore error here (e.g. killed buffer).
+            (error nil))
+          (setq count  (1+ count)))
+        (when msg-p (message "Set %d bookmarks" count))))))
+
+
+;; We could make the `occur' code work for Emacs 20 & 21 also, but you would not be able to
+;; delete some occurrences and bookmark only the remaining ones.
+
+(when (> emacs-major-version 21)
+  (defun bmkp-occur-target-set (&optional prefix) ; Bound to `C-c C-b' in Occur mode
+    "Set a bookmark at the start of the line for this `(multi-)occur' hit.
+You are prompted for the bookmark name.  But with a prefix arg, you
+are prompted only for a PREFIX string.  In that case, and in Lisp
+code, the bookmark name is PREFIX followed by the buffer name of the
+hit, followed by the line number of the hit.
+
+You can use this only in `Occur' mode (commands such as `occur' and
+`multi-occur')."
+    (interactive "P")
+    (unless (eq major-mode 'occur-mode) (error "You must be in `occur-mode'"))
+    (let* ((line  (and prefix
+                       (save-excursion
+                         (forward-line 0)
+                         ;; We could use [: ] here, to handle `moccur', but that loses anyway for
+                         ;; `occur-mode-find-occurrence', so we would need other hoops too.
+                         (re-search-forward "^\\s-+\\([0-9]+\\):" (line-end-position) 'NOERROR)
+                         (or (format "%5d" (string-to-number (match-string 1)))  ""))))
+           (mkr   (occur-mode-find-occurrence))
+           (buf   (marker-buffer mkr)))
+      (save-excursion (with-current-buffer buf
+                        (goto-char mkr)
+                        (if (not prefix)
+                            (call-interactively #'bookmark-set)
+                          (when (interactive-p)
+                            (setq prefix  (read-string "Prefix for bookmark name: ")))
+                          (unless (stringp prefix) (setq prefix  ""))
+                          (bookmark-set (format "%s%s, line %s" prefix buf line) 99 'INTERACTIVEP)))))))
+
+(when (> emacs-major-version 21)
+  (defun bmkp-occur-target-set-all (&optional prefix msg-p) ; Bound to `C-c C-M-b' in Occur mode
+    "Set a bookmark for each hit of a `(multi-)occur' buffer.
+NOTE: You can use `C-x C-q' to make the buffer writable and then
+      remove any hits that you do not want to bookmark.  Only the hits
+      remaining in the buffer are bookmarked.
+
+Interactively, you are prompted for a PREFIX string to prepend to each
+bookmark name, the rest of which is the buffer name of the hit
+followed by its line number.
+
+You can use this only in `Occur' mode (commands such as `occur' and
+`multi-occur').
+
+See also command `bmkp-occur-create-autonamed-bookmarks', which
+creates autonamed bookmarks to all `occur' and `multi-occur' hits.
+
+Non-interactively, non-nil MSG-P means prompt and show status
+messages."
+    (interactive (list (read-string "Prefix for bookmark name: ") 'MSG))
+    (when (and msg-p  (not (y-or-n-p "This will bookmark *EACH* hit in the buffer.  Continue? ")))
+      (error "OK - canceled"))
+    (let ((count  0))
+      (save-excursion
+        (goto-char (point-min))
+        (while (condition-case nil
+                   (progn (occur-next) t) ; "No more matches" ends loop.
+                 (error nil))
+          (condition-case nil
+              (bmkp-occur-target-set prefix) ; Ignore error here (e.g. killed buffer).
+            (error nil))
+          (setq count  (1+ count)))
+        (when msg-p (message "Set %d bookmarks" count))))))
+
+
+;;(@* "Bookmark Links")
+;;  *** Bookmark Links ***
+
+(when (> emacs-major-version 21)
+
+  (defun bmkp-bookmark-linked-at (&optional position msgp)
+    "Return the bookmark linked at POSITION (default: point), or nil if none."
+    (interactive "d\np")
+    (unless position (setq position  (point)))
+    (let ((bmk  (get-text-property position 'bmkp-bookmark)))
+      (prog1 bmk (when msgp (if bmk (bmkp-describe-bookmark bmk) (message "No bookmark here"))))))
+
+  (defun bmkp-bookmark-linked-at-mouse (event)
+    "Return the bookmark linked at the mouse position."
+    (interactive "e")
+    (bmkp-bookmark-linked-at (posn-point (event-end event)) 'MSG))
+
+  (defun bmkp-jump-to-bookmark-linked-at (&optional position)
+    "Jump to the bookmark linked at POSITION (default: point).
+If a bookmark is linked at POSITION then jump to it.  Else raise an error."
+    (interactive "d")
+    (let ((bmk  (bmkp-bookmark-linked-at position)))
+      (unless bmk (error "No bookmark here"))
+      (bookmark-jump-other-window bmk)))
+
+  (defun bmkp-jump-to-bookmark-linked-at-mouse (event)
+    "Jump to the bookmark linked at the mouse position."
+    (interactive "e")
+    (bmkp-jump-to-bookmark-linked-at (posn-point (event-end event))))
+
+  (defun bmkp-insert-bookmark-link (bookmark text &optional position)
+    "Put a link to BOOKMARK on the active region or at point.
+You are prompted for the bookmark name.
+If the region is active and nonempty then put the link on its text.
+
+Otherwise, you are prompted for the link text, which is inserted at
+point.  The default text for this is the BOOKMARK name.  An unlinked
+`SPC' char is inserted after the link, unless it is at the end of a
+line.
+
+Using `?' or double-clicking `mouse-1' on the link describes the
+BOOKMARK.  Using `RET' or `mouse-2' on it jumps to BOOKMARK in another
+window.
+
+BOOKMARK is a bookmark name or a bookmark record.
+
+Non-interactively, if the region is inactive or empty then TEXT is the
+link text, and it is inserted at POSITION (point if POSITION is nil)."
+    (interactive
+     (let* ((bmk  (bookmark-completing-read "Bookmark"))
+            (txt  (if (and transient-mark-mode  mark-active  (> (region-end) (region-beginning)))
+                      (buffer-substring-no-properties (region-end) (region-beginning))
+                    (read-string "Insert text: " nil nil bmk))))
+       (list bmk txt)))
+    (with-buffer-modified-unmodified
+        (let* ((regionp  (and transient-mark-mode  mark-active  (> (region-end) (region-beginning))))
+               (beg      (if regionp (region-beginning) (or position  (point))))
+               (end      (and regionp  (region-end)))
+               (bmk      (bmkp-get-bookmark bookmark))
+               (map      (make-sparse-keymap)))
+          (unless bmk (error "No such bookmark"))
+          ;; Use `copy-sequence'.  The bookmark name in the bookmark might change.
+          (setq bookmark  (copy-sequence (bmkp-bookmark-name-from-record bmk)))
+          (put-text-property 0 (length bookmark) 'bmkp-bookmark bmk bookmark)
+          (define-key map "?"              'bmkp-bookmark-linked-at)
+          (define-key map "\r"             'bmkp-jump-to-bookmark-linked-at)
+          (define-key map [double-mouse-1] 'bmkp-bookmark-linked-at-mouse)
+          (define-key map [mouse-2]        'bmkp-jump-to-bookmark-linked-at-mouse)
+          (define-key map [follow-link]    'mouse-face)
+          (unless regionp (insert text))
+          (add-text-properties beg (or end  (point))
+                               `(bmkp-bookmark     ,bookmark
+                                 keymap            ,map
+                                 font-lock-ignore  t ; Prevent font-lock from changing the face.
+                                 face              link
+                                 mouse-face        highlight
+                                 help-echo
+                                 "RET, mouse-2: jump to bookmark; ?, double-mouse-1: describe bookmark"))
+          (unless (or regionp  (eolp)) (insert " ")))))
+
+  )
+
+
+;;(@* "Other Bookmark+ Functions (`bmkp-*')")
+;;  *** Other Bookmark+ Functions (`bmkp-*') ***
+
+;;;###autoload (autoload 'bmkp-describe-bookmark "bookmark+")
+(defun bmkp-describe-bookmark (bookmark &optional defn) ; Bound to `C-h M'
+  "Describe BOOKMARK.
+With a prefix argument, show the internal definition of the bookmark.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'.
+
+Starting with Emacs 22, if the file is an image file then:
+* Show a thumbnail of the image as well.
+* If you have command-line tool `exiftool' installed and in your
+  `$PATH' or `exec-path', then show EXIF data (metadata) about the
+  image.  See standard Emacs library `image-dired.el' for more
+  information about `exiftool'"
+  (interactive (list (bookmark-completing-read "Describe bookmark"
+                                               (or (and (fboundp 'bmkp-default-lighted)
+                                                        (bmkp-default-lighted))
+                                                   (bmkp-default-bookmark-name)))
+                     current-prefix-arg))
+  (if defn
+      (bmkp-describe-bookmark-internals bookmark)
+    (setq bookmark  (bmkp-get-bookmark bookmark))
+    (help-setup-xref (list #'bmkp-describe-bookmark bookmark) (interactive-p))
+    (let ((help-text  (bmkp-bookmark-description bookmark)))
+      (bmkp-with-help-window "*Help*" (princ help-text) (bmkp-add-jump-to-list-button bookmark))
+      (with-current-buffer "*Help*"
+        (save-excursion
+          (goto-char (point-min))
+          (when (re-search-forward "@#%&()_IMAGE-HERE_()&%#@\\(.+\\)" nil t)
+            (let* ((image-file        (match-string 1))
+                   (image-string      (save-match-data
+                                        (apply #'propertize "X"
+                                               `(display
+                                                 ,(append (image-dired-get-thumbnail-image image-file)
+                                                          '(:margin 10))
+                                                 rear-nonsticky (display)
+                                                 mouse-face highlight
+                                                 follow-link t
+                                                 help-echo "`mouse-2' or `RET': Show full image"
+                                                 keymap
+                                                 (keymap
+                                                  (mouse-2
+                                                   . (lambda (e) (interactive "e")
+                                                       (find-file ,image-file)))
+                                                  (13
+                                                   . (lambda () (interactive)
+                                                       (find-file ,image-file))))))))
+                   (buffer-read-only  nil))
+              (replace-match image-string)))))
+      help-text)))
+
+(defun bmkp-bookmark-description (bookmark &optional no-image)
+  "Help-text description of BOOKMARK.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'.
+
+Starting with Emacs 22 and unless optional arg NO-IMAGE is non-nil, if
+the file is an image file then the description includes the following:
+* A placeholder for a thumbnail image: \"@#%&()_IMAGE-HERE_()&%#@\"
+* EXIF data (metadata) about the image, provided you have command-line
+  tool `exiftool' installed and in your `$PATH' or `exec-path'.  See
+  standard Emacs library `image-dired.el' for more information about
+  `exiftool'."
+  (setq bookmark  (bmkp-get-bookmark bookmark))
+  (let ((print-circle     bmkp-propertize-bookmark-names-flag) ; For `pp-to-string'
+        (print-gensym     bmkp-propertize-bookmark-names-flag) ; For `pp-to-string'
+        (print-length     nil)          ; For `pp-to-string'
+        (print-level      nil)          ; For `pp-to-string'
+        (bname            (bmkp-bookmark-name-from-record bookmark))
+        (buf              (bmkp-get-buffer-name bookmark))
+        (file             (bookmark-get-filename bookmark))
+        (image-p          (bmkp-image-bookmark-p bookmark))
+        (location         (bookmark-prop-get bookmark 'location))
+        (start            (bookmark-get-position bookmark))
+        (end              (bmkp-get-end-position bookmark))
+        (created          (bookmark-prop-get bookmark 'created))
+        (time             (bmkp-get-visit-time bookmark))
+        (visits           (bmkp-get-visits-count bookmark))
+        (tags             (mapcar #'bmkp-tag-name (bmkp-get-tags bookmark)))
+        (sequence-p       (bmkp-sequence-bookmark-p bookmark))
+        (function-p       (bmkp-function-bookmark-p bookmark))
+        (kmacro-p         (bmkp-kmacro-list-bookmark-p bookmark))
+        (variable-list-p  (bmkp-variable-list-bookmark-p bookmark))
+        (search-hits-p    (bmkp-icicles-search-hits-bookmark-p bookmark))
+        (non-invokable-p  (bmkp-non-invokable-bookmark-p bookmark))
+        (desktop-p        (bmkp-desktop-bookmark-p bookmark))
+        (bookmark-file-p  (bmkp-bookmark-file-bookmark-p bookmark))
+        (snippet-p        (bmkp-snippet-bookmark-p bookmark))
+        (dired-p          (bmkp-dired-bookmark-p bookmark))
+        (gnus-p           (bmkp-gnus-bookmark-p bookmark))
+        (info-p           (bmkp-info-bookmark-p bookmark))
+        (man-p            (bmkp-man-bookmark-p bookmark))
+        (url-p            (bmkp-url-bookmark-p bookmark))
+        (eww-p            (and (fboundp 'bmkp-eww-bookmark-p)  (bmkp-eww-bookmark-p bookmark))) ; Emacs 25+
+        (w3m-p            (bmkp-w3m-bookmark-p bookmark))
+        (temp-p           (bmkp-temporary-bookmark-p bookmark))
+        (annot            (bookmark-get-annotation bookmark))
+        non-file-p no-position-p)
+    (setq non-file-p     (equal file bmkp-non-file-filename)
+          no-position-p  (not start))
+    (when (or sequence-p  function-p  variable-list-p  kmacro-p  search-hits-p) (setq no-position-p  t))
+    (let* ((temp-text  (if temp-p "TEMPORARY " ""))
+           (help-text
+            (concat
+             (format "%sBookmark `%s'\n%s\n\n" temp-text bname
+                     (make-string (+ 11 (length temp-text) (length bname)) ?-))
+             (cond (sequence-p       (concat "Sequence:\n\t"
+                                             (mapconcat (lambda (bname)
+                                                          (let ((name  (copy-sequence bname)))
+                                                            (set-text-properties 0 (length name) () name)
+                                                            name))
+                                                        (bookmark-prop-get bookmark 'sequence)
+                                                        "\n\t")
+                                             "\n"))
+                   (function-p       (let ((fn            (bookmark-prop-get bookmark 'function)))
+                                       (if (symbolp fn)
+                                           (format "Function:\t\t%s\n" fn)
+                                         (format "Function:\n%s\n"
+                                                 (pp-to-string (bookmark-prop-get bookmark 'function))))))
+                   (kmacro-p         (format "Keyboard Macro List (MACRO COUNT COUNT-FORMAT):\n\n%s\n"
+                                             (pp-to-string (bookmark-prop-get bookmark 'kmacros))))
+                   (variable-list-p  (format "Variable list:\n%s\n"
+                                             (pp-to-string (bookmark-prop-get bookmark 'variables))))
+                   (search-hits-p    (format "Icicles search hits:\n%s\n\n"
+                                             (mapconcat (lambda (hit)
+                                                          (let ((hit-copy  (copy-sequence hit)))
+                                                            (set-text-properties 0 (length hit-copy) ()
+                                                                                 hit-copy)
+                                                            hit-copy))
+                                                        (bookmark-prop-get bookmark 'hits)
+                                                        "\n\t")))
+                   (non-invokable-p  (format "Non-invokable:\n\n%s"
+                                             (let ((desc  (bookmark-prop-get bookmark 'filter-description)))
+                                               (if desc
+                                                   (format "Isearch filter:\n%s\n" desc)
+                                                 ""))))
+                   (gnus-p           (format "Gnus, group:\t\t%s, article: %s, message-id: %s\n"
+                                             (bookmark-prop-get bookmark 'group)
+                                             (bookmark-prop-get bookmark 'article)
+                                             (bookmark-prop-get bookmark 'message-id)))
+                   (man-p            (format "UNIX `man' page for:\t`%s'\n"
+                                             (or (bookmark-prop-get bookmark 'man-args)
+                                                 ;; WoMan has no variable for the cmd name.
+                                                 (bookmark-prop-get bookmark 'buffer-name))))
+                   (info-p           (and file  (format "Info node:\t\t(%s) %s\n"
+                                                        (file-name-nondirectory file)
+                                                        (bookmark-prop-get bookmark 'info-node))))
+                   (eww-p            (and file  (format "EWW URL:\t\t%s\n" file))) ; Emacs 25+
+                   (w3m-p            (and file  (format "W3m URL:\t\t%s\n" file)))
+                   (url-p            (format "URL:\t\t\t%s\n" location))
+                   (desktop-p        (format "Desktop file:\t\t%s\n"
+                                             (bookmark-prop-get bookmark 'desktop-file)))
+                   (bookmark-file-p  (format "Bookmark file:\t\t%s\n"
+                                             (bookmark-prop-get bookmark 'bookmark-file)))
+                   (snippet-p        (format "Snippet for `kill-ring'.\n"))
+                   (dired-p          (and file
+                                          (let ((switches  (bookmark-prop-get bookmark 'dired-switches))
+                                                (marked    (length (bookmark-prop-get bookmark
+                                                                                      'dired-marked)))
+                                                (inserted  (length (bookmark-prop-get bookmark
+                                                                                      'dired-subdirs)))
+                                                (hidden    (length (bookmark-prop-get bookmark
+                                                                                      'dired-hidden-dirs))))
+                                            (format "Dired%s:%s\t\t%s\nMarked:\t\t\t%s\n\
+Inserted subdirs:\t%s\nHidden subdirs:\t\t%s\n"
+                                                    (if switches (format " `%s'" switches) "")
+                                                    (if switches "" (format "\t"))
+                                                    (expand-file-name file)
+                                                    marked inserted hidden))))
+                   (non-file-p       (or (and location  (format "Location:\t\t%s\n" location))
+                                         (and buf  (format "Buffer:\t\t\t%s\n" buf))))
+                   (file             (concat (format "File:\t\t\t%s\n" (file-name-nondirectory file))
+                                             (let ((dir  (file-name-directory (expand-file-name file))))
+                                               (and dir  (format "Directory:\t\t%s\n" dir)))))
+                   (t                "Unknown\n"))
+             (unless no-position-p
+               (if (bmkp-region-bookmark-p bookmark)
+                   (format "Region:\t\t\t%d to %d (%d chars)\n" start end (- end start))
+                 (format "Position:\t\t%d\n" start)))
+             (and visits     (format "Visits:\t\t\t%d\n" visits))
+             (and time       (format "Last visit:\t\t%s\n" (format-time-string "%c" time)))
+             (and created    (format "Creation:\t\t%s\n" (format-time-string "%c" created)))
+             (and tags       (format "Tags:\n \"%s\"\n" (mapconcat #'identity tags "\"\n \"")))
+             (and annot      (format "\nAnnotation:\n%s\n" annot))
+             (and snippet-p  (format "\nSnippet:\n%s\n" (bookmark-prop-get bookmark 'text)))
+             (and (not no-image)
+                  file
+                  (fboundp 'image-file-name-regexp) ; In `image-file.el' (Emacs 22+).
+                  (bmkp-string-match-p (image-file-name-regexp) file)
+                  (if (fboundp 'display-graphic-p) (display-graphic-p) window-system)
+                  (require 'image-dired nil t)
+                  (image-dired-get-thumbnail-image file)
+                  (concat "\n@#%&()_IMAGE-HERE_()&%#@" file "\n"))
+             (and (not no-image)
+                  file
+                  (fboundp 'image-file-name-regexp) ; In `image-file.el' (Emacs 22+).
+                  (bmkp-string-match-p (image-file-name-regexp) file)
+                  (progn (message "Gathering image data...") t)
+                  (condition-case nil
+                      (let ((all  (bmkp-all-exif-data (expand-file-name file))))
+                        (concat
+                         (and all  (not (zerop (length all)))
+                              (format "\nImage Data (EXIF)\n-----------------\n%s"
+                                      all))))
+                    (error nil))))))
+      help-text)))
+
+(when (and (> emacs-major-version 21)
+           (condition-case nil (require 'help-mode nil t) (error nil))
+           (get 'help-xref 'button-category-symbol)) ; In `button.el'
+  (define-button-type 'bmkp-jump-to-list-button
+    :supertype 'help-xref
+    'help-function #'bmkp-jump-to-list
+    'help-echo
+    (purecopy "mouse-2, RET: Show in `*Bookmark List*'")))
+
+(defun bmkp-add-jump-to-list-button (bookmark)
+  "Add a [Show in `*Bookmark List*'] button for BOOKMARK."
+  (with-current-buffer "*Help*"
+    (let ((buffer-read-only  nil))
+      ;; Add button to go to the bookmark entry in `*Bookmark List*'.
+      ;; Not for Emacs 21.3 - its `help-insert-xref-button' signature is different.
+      (when (and (> emacs-major-version 21) ; In `help-mode.el'.
+                 (condition-case nil (require 'help-mode nil t) (error nil))
+                 (fboundp 'help-insert-xref-button))
+        (goto-char (point-min)) (forward-line 2)
+        (help-insert-xref-button "[Show in `*Bookmark List*']"
+                                 #'bmkp-jump-to-list-button
+                                 (bookmark-name-from-record bookmark))
+        (insert "\n")))))
+
+;; This is the same as `help-all-exif-data' in `help-fns+.el', but we avoid requiring that library.
+(defun bmkp-all-exif-data (file)
+  "Return all EXIF data from FILE, using command-line tool `exiftool'."
+  (with-temp-buffer
+    (delete-region (point-min) (point-max))
+    (unless (eq 0 (call-process shell-file-name nil t nil shell-command-switch
+                                (format "exiftool -All \"%s\"" file)))
+      (error "Could not get EXIF data"))
+    (buffer-string)))
+
+
+;;;###autoload (autoload 'bmkp-describe-bookmark-internals "bookmark+")
+(defun bmkp-describe-bookmark-internals (bookmark)
+  "Show the internal definition of the bookmark BOOKMARK.
+BOOKMARK is a bookmark name or a bookmark record.
+If it is a record then it need not belong to `bookmark-alist'."
+  (interactive (list (bookmark-completing-read "Describe bookmark" (bmkp-default-bookmark-name))))
+  ;; Work with a copy of the bookmark, so we can unpropertize the name.
+  (setq bookmark  (copy-sequence (bmkp-get-bookmark bookmark)))
+  (help-setup-xref (list #'bmkp-describe-bookmark-internals bookmark) (interactive-p))
+  (let* ((bname         (copy-sequence (bmkp-bookmark-name-from-record bookmark)))
+         (IGNORE        (set-text-properties 0 (length bname) nil bname)) ; Strip properties from name.
+         (bmk           (cons bname (bmkp-bookmark-data-from-record bookmark))) ; Fake bmk with stripped name.
+         (print-circle  bmkp-propertize-bookmark-names-flag) ; For `pp-to-string'
+         (print-gensym  bmkp-propertize-bookmark-names-flag) ; For `pp-to-string'
+         (print-length  nil)            ; For `pp-to-string'
+         (print-level   nil)            ; For `pp-to-string'
+         (help-text     (format "Bookmark `%s'\n%s\n\n%s" bname (make-string (+ 11 (length bname)) ?-)
+                                (pp-to-string bmk))))
+    (bmkp-with-help-window "*Help*" (princ help-text))
+    (bmkp-add-jump-to-list-button bookmark)
+    help-text))
+
+(defun bmkp-annotation-or-bookmark-description (bookmark)
+  "Return the annotation or description of BOOKMARK as a string.
+If BOOKMARK has an annotation then use that; else the description."
+  (or (bookmark-get-annotation bookmark)
+      (bmkp-bookmark-description bookmark)))
+
+;;;###autoload (autoload 'bmkp-list-defuns-in-commands-file "bookmark+")
+(defun bmkp-list-defuns-in-commands-file ()
+  "List the functions defined in `bmkp-bmenu-commands-file'.
+Typically, these are all commands."
+  (interactive)
+  (when (and bmkp-bmenu-commands-file  (file-readable-p bmkp-bmenu-commands-file))
+    (when (file-directory-p bmkp-bmenu-commands-file)
+      (error "`%s' is a directory, not a file" bmkp-bmenu-commands-file))
+    (let ((fns  ())
+          (buf  (let ((enable-local-variables  nil))
+                  (find-file-noselect bmkp-bmenu-commands-file))))
+      (help-setup-xref (list #'bmkp-list-defuns-in-commands-file) (interactive-p))
+      (with-current-buffer buf
+        (goto-char (point-min))
+        (while (not (eobp))
+          (when (re-search-forward "\\s-*(defun \\([^ \t\n(\"]+\\)[ \t\n(]" nil 'move)
+            (push (match-string 1) fns)))
+        (setq fns  (nreverse fns)
+              fns  (sort fns 'string-lessp)))
+      (when (buffer-live-p buf) (kill-buffer buf))
+      (bmkp-with-help-window "*Help*"
+        (princ "Bookmark Commands You Defined (in `bmkp-bmenu-commands-file')") (terpri)
+        (princ "------------------------------------------------------------------") (terpri)
+        (terpri)
+        (let ((non-dups  (bmkp-remove-dups fns)))
+          (dolist (fn  non-dups)
+            (if (and (fboundp (intern fn))  (fboundp 'help-insert-xref-button))
+                (with-current-buffer "*Help*"
+                  (goto-char (point-max))
+                  (help-insert-xref-button fn 'help-function (intern fn) (commandp (intern fn))))
+              (princ fn))
+            (let ((dups   (member fn fns)) ; Sorted, so all dups are together.
+                  (count  0))
+              (while (equal fn (car dups))
+                (setq count  (1+ count)
+                      dups   (cdr dups)))
+              (when (> count 1) (princ (format "  (%d times)" count))))
+            (terpri)))
+        (help-make-xrefs (current-buffer)))
+      fns)))
+
+(defun bmkp-root-or-sudo-logged-p ()
+  "Return t if the user logged in using Tramp as `root' or `sudo'.
+Otherwise, return nil."
+  (catch 'break
+    (dolist (ii  (mapcar #'buffer-name (buffer-list)))
+      (when (bmkp-string-match-p "*tramp/\\(su\\|sudo\\) ." ii) (throw 'break t)))))
+
+(defun bmkp-position-post-context (breg)
+  "Return `bookmark-search-size' chars, starting at position BREG.
+Return nil if there are not that many chars.
+This is text that follows the bookmark's `position'.
+This is used for a non-region bookmark."
+  (and (>= (- (point-max) breg) bookmark-search-size)
+       (buffer-substring-no-properties breg (+ breg bookmark-search-size))))
+
+(defun bmkp-position-post-context-region (breg ereg)
+  "Return the region prefix, at BREG.
+Return at most `bmkp-region-search-size' or (- EREG BREG) chars.
+This is text that follows the bookmark's `position'.
+This is used for a region bookmark."
+  (buffer-substring-no-properties breg (+ breg (min bmkp-region-search-size (- ereg breg)))))
+
+(defun bmkp-position-pre-context (breg)
+  "Return `bookmark-search-size' chars that precede BREG.
+Return nil if there are not that many chars.
+This is text that precedes the bookmark's `position'.
+This is used for a non-region bookmark."
+  (and (>= (- breg (point-min)) bookmark-search-size)
+       (buffer-substring-no-properties breg (- breg bookmark-search-size))))
+
+(defun bmkp-position-pre-context-region (breg)
+  "Return the text preceding the region beginning, BREG.
+Return at most `bmkp-region-search-size' chars.
+This is text that precedes the bookmark's `position'.
+This is used for a region bookmark."
+  (buffer-substring-no-properties (max (- breg bmkp-region-search-size) (point-min)) breg))
+
+(defun bmkp-end-position-pre-context (breg ereg)
+  "Return the region suffix, ending at EREG.
+Return at most `bmkp-region-search-size' or (- EREG BREG) chars.
+This is text that precedes the bookmark's `end-position'."
+  (buffer-substring-no-properties (- ereg (min bmkp-region-search-size (- ereg breg))) ereg))
+
+(defun bmkp-end-position-post-context (ereg)
+  "Return the text following the region end, EREG.
+Return at most `bmkp-region-search-size' chars.
+This is text that follows the bookmark's `end-position'."
+  (buffer-substring-no-properties ereg (+ ereg (min bmkp-region-search-size (- (point-max) ereg)))))
+
+(defun bmkp-position-after-whitespace (position)
+  "Move forward from POSITION, skipping over whitespace.  Return point."
+  (goto-char position)  (skip-chars-forward " \n\t" (point-max))  (point))
+
+(defun bmkp-position-before-whitespace (position)
+  "Move backward from POSITION, skipping over whitespace.  Return point."
+  (goto-char position)  (skip-chars-backward " \n\t" (point-min))  (point))
+
+(defun bmkp-save-new-region-location (bookmark beg end)
+  "Update and save `bookmark-alist' for BOOKMARK, relocating its region.
+Saving happens according to `bookmark-save-flag'.
+BOOKMARK is a bookmark record.
+BEG and END are the new region limits for BOOKMARK.
+Do nothing and return nil if `bmkp-save-new-location-flag' is nil.
+Otherwise, return non-nil if region was relocated."
+  (and bmkp-save-new-location-flag
+       (y-or-n-p "Region relocated.  Do you want to save new region limits? ")
+       (progn
+         (bookmark-prop-set bookmark 'front-context-string (bmkp-position-post-context-region beg end))
+         (bookmark-prop-set bookmark 'rear-context-string (bmkp-position-pre-context-region beg))
+         (bookmark-prop-set bookmark 'front-context-region-string (bmkp-end-position-pre-context beg end))
+         (bookmark-prop-set bookmark 'rear-context-region-string (bmkp-end-position-post-context end))
+         (bookmark-prop-set bookmark 'position beg)
+         (bookmark-prop-set bookmark 'end-position end)
+         (bmkp-maybe-save-bookmarks)
+         t)))
+
+(defun bmkp-handle-region-default (bookmark)
+  "Default function to handle BOOKMARK's region.
+BOOKMARK is a bookmark name or a bookmark record.
+Relocate the region if necessary, then activate it.
+If region was relocated, save it if user confirms saving."
+  ;; Relocate by searching from the beginning (and possibly the end) of the buffer.
+  (let* (;; Get bookmark object once and for all.
+         ;; We should know BOOKMARK is a bookmark record (not a name), but play it safe.
+         (bmk              (bmkp-get-bookmark bookmark))
+         (bor-str          (bookmark-get-front-context-string bmk))
+         (eor-str          (bookmark-prop-get bmk 'front-context-region-string))
+         (br-str           (bookmark-get-rear-context-string bmk))
+         (ar-str           (bookmark-prop-get bookmark 'rear-context-region-string))
+         (pos              (bookmark-get-position bmk))
+         (end-pos          (bmkp-get-end-position bmk))
+         (reg-retrieved-p  t)
+         (reg-relocated-p  nil))
+    (unless (and end-pos
+                 (string= bor-str (buffer-substring-no-properties
+                                   (point) (min (point-max) (+ (point) (length bor-str)))))
+                 (string= eor-str (buffer-substring-no-properties
+                                   end-pos (max (point-min) (- end-pos (length bor-str))))))
+      ;; Relocate region by searching from beginning (and possibly from end) of buffer.
+      (let ((beg  nil)
+            (end  nil))
+        ;;  Go to bob and search forward for END.
+        (goto-char (point-min))
+        (if (search-forward eor-str (point-max) t) ; Find END, using `eor-str'.
+            (setq end  (point))
+          ;; Verify that region is not before context.
+          (unless (search-forward br-str (point-max) t)
+            (when (search-forward ar-str (point-max) t) ; Find END, using `ar-str'.
+              (setq end  (match-beginning 0)
+                    end  (and end  (bmkp-position-before-whitespace end))))))
+        ;; If failed to find END, go to eob and search backward for BEG.
+        (unless end (goto-char (point-max)))
+        (if (search-backward bor-str (point-min) t) ; Find BEG, using `bor-str'.
+            (setq beg  (point))
+          ;; Verify that region is not after context.
+          (unless (search-backward ar-str (point-min) t)
+            (when (search-backward br-str (point-min) t) ; Find BEG, using `br-str'.
+              (setq beg  (match-end 0)
+                    beg  (and beg  (bmkp-position-after-whitespace beg))))))
+        (setq reg-retrieved-p  (or beg  end)
+              reg-relocated-p  reg-retrieved-p
+              ;; If only one of BEG or END was found, the relocated region is only
+              ;; approximate (keep the same length).  If both were found, it is exact.
+              pos              (or beg  (and end  pos  end-pos  (- end (- end-pos pos)))  pos)
+              end-pos          (or end  (and beg  pos  end-pos  (+ pos (- end-pos pos)))  end-pos))))
+    ;; Region is available. Activate it and maybe save it.
+    (cond (reg-retrieved-p
+           (when pos (goto-char pos))
+           (when end-pos (push-mark end-pos 'nomsg 'activate))
+           (when bmkp-show-end-of-region-flag
+             (let ((end-win  (save-excursion (forward-line (window-height)) (line-end-position))))
+               ;; Bounce point and mark.
+               (save-excursion (sit-for 0.6) (exchange-point-and-mark) (sit-for 1))
+               ;; Recenter if region end is not visible.
+               (when (and end-pos  (> end-pos end-win)) (recenter 1))))
+           ;; Maybe save region.
+           (if (and reg-relocated-p  (bmkp-save-new-region-location bmk pos end-pos))
+               (message "Saved relocated region%s" (if (and pos  end-pos)
+                                                       (format " (from %d to %d)" pos end-pos)
+                                                     ""))
+             (when (and pos  end-pos) (message "Region is from %d to %d" pos end-pos)))
+           (when (and pos  end-pos)
+             (goto-char pos)
+             (push-mark end-pos 'nomsg 'activate)
+             (setq deactivate-mark  nil)))
+          ((and pos  end-pos) ; No region.  Go to old start.  Don't push-mark.
+           (goto-char pos) (forward-line 0)
+           (message "No region from %d to %d" pos end-pos)))))
+
+(defun bmkp-goto-position (bookmark file buf bufname pos forward-str behind-str)
+  "Go to a bookmark that has no region.
+Update the recorded position if POS and `bmkp-save-new-location-flag'
+are non-nil.
+
+Arguments are respectively the bookmark, its file, buffer, buffer
+name, recorded position, and the context strings for the position."
+  (if (and file  (file-readable-p file)  (not (buffer-live-p buf)))
+;;; $$$$$$$ (with-current-buffer (let ((enable-local-variables  ())) (find-file-noselect file))
+      (with-current-buffer (find-file-noselect file) (setq buf  (buffer-name)))
+    ;; No file found.  See if a non-file buffer exists for this.  If not, raise error.
+    (unless (or (and buf  (get-buffer buf))
+                (and bufname  (get-buffer bufname)  (not (string= buf bufname))))
+      (signal 'file-error `("Jumping to bookmark" ,(format "Cannot access file `%s' or buffer `%s'"
+                                                           file bufname)))))
+  (set-buffer (or buf  bufname))
+  (when bmkp-jump-display-function
+    (save-current-buffer (funcall bmkp-jump-display-function (current-buffer))))
+  (setq deactivate-mark  t)
+  (raise-frame)
+  (when pos (goto-char pos))
+  ;; Try to relocate position.
+  ;; Search forward first.  Then, if FORWARD-STR exists and was found in the file, search
+  ;; backward for BEHIND-STR.  The rationale is that if text was inserted between the two
+  ;; in the file, then it's better to end up before point, so you can see the text, rather
+  ;; than after it and not see it.
+  (when (and forward-str  (search-forward forward-str (point-max) t))
+    (goto-char (match-beginning 0)))
+  (when (and behind-str  (search-backward behind-str (point-min) t))  (goto-char (match-end 0)))
+  (when (and (not (equal pos (point)))  bmkp-save-new-location-flag)
+    (bookmark-prop-set bookmark 'position     (point))
+    (bookmark-prop-set bookmark 'end-position (point))
+    ;; Perhaps we should treat the case of a bookmark that had position 0 changing to position 1 specially,
+    ;; by passing non-nil SAME-COUNT-P arg to `bmkp-maybe-save-bookmarks'.  On the other hand, if initially
+    ;; 0 then the bookmark does not claim that the file is non-empty.  If now set to 1 then we know it is.
+    ;; Leave it this way, at least for now.  The consequence is that the user will see that bookmarks have
+    ;; modified (e.g. `Save' is enabled in the menu), even though nothing much has changed.
+    (bmkp-maybe-save-bookmarks))
+  (not (equal pos (point))))            ; Return value indicates whether POS was accurate.
+
+(defun bmkp-jump-sequence (bookmark)
+  "Handle a sequence bookmark BOOKMARK.
+Handler function for sequence bookmarks.
+BOOKMARK is a bookmark name or a bookmark record."
+  (dolist (bmk  (bookmark-prop-get bookmark 'sequence))
+    (bookmark--jump-via bmk bmkp-sequence-jump-display-function))
+  (message "Done invoking bookmarks in sequence `%s'"
+           (if (stringp bookmark) bookmark (bmkp-bookmark-name-from-record bookmark))))
+
+(defun bmkp-jump-function (bookmark)
+  "Handle a function bookmark BOOKMARK.
+Handler function for function bookmarks.
+BOOKMARK is a bookmark name or a bookmark record."
+  (let ((fn  (bookmark-prop-get bookmark 'function)))
+    (cond ((functionp fn) (funcall fn))
+          ((vectorp fn)
+           (execute-kbd-macro fn current-prefix-arg)))))
+
+(defun bmkp-make-bookmark-list-record ()
+  "Create and return a bookmark-list bookmark record.
+This records the current state of buffer `*Bookmark List*': the sort
+order, filter function, regexp pattern, title, and omit list."
+  (let ((state  `((last-sort-comparer            . ,bmkp-sort-comparer)
+                  (last-reverse-sort-p           . ,bmkp-reverse-sort-p)
+                  (last-reverse-multi-sort-p     . ,bmkp-reverse-multi-sort-p)
+                  (last-bmenu-filter-function    . ,bmkp-bmenu-filter-function)
+                  (last-bmenu-filter-pattern     . ,bmkp-bmenu-filter-pattern)
+                  (last-bmenu-omitted-bookmarks  . ,(bmkp-maybe-unpropertize-bookmark-names
+                                                     bmkp-bmenu-omitted-bookmarks))
+                  (last-bmenu-title              . ,bmkp-bmenu-title)
+                  (last-bmenu-toggle-filenames   . ,bookmark-bmenu-toggle-filenames))))
+    `(,@(bookmark-make-record-default 'NO-FILE 'NO-CONTEXT)
+      (filename      . ,bmkp-non-file-filename)
+      (bookmark-list . ,state)
+      (handler       . bmkp-jump-bookmark-list))))
+
+(add-hook 'bookmark-bmenu-mode-hook
+          (lambda () (set (make-local-variable 'bookmark-make-record-function)
+                          'bmkp-make-bookmark-list-record)))
+
+(defun bmkp-jump-bookmark-list (bookmark)
+  "Jump to bookmark-list bookmark BOOKMARK.
+Handler function for record returned by
+`bmkp-make-bookmark-list-record'.
+BOOKMARK is a bookmark name or a bookmark record."
+  (let ((state  (bookmark-prop-get bookmark 'bookmark-list)))
+    (setq bmkp-sort-comparer               (cdr (assq 'last-sort-comparer            state))
+          bmkp-reverse-sort-p              (cdr (assq 'last-reverse-sort-p           state))
+          bmkp-reverse-multi-sort-p        (cdr (assq 'last-reverse-multi-sort-p     state))
+          bmkp-bmenu-filter-function       (cdr (assq 'last-bmenu-filter-function    state))
+          bmkp-bmenu-filter-pattern        (or (cdr (assq 'last-bmenu-filter-pattern state))  "")
+          bmkp-bmenu-omitted-bookmarks     (cdr (assq 'last-bmenu-omitted-bookmarks  state))
+          bmkp-bmenu-title                 (cdr (assq 'last-bmenu-title              state))
+          bookmark-bmenu-toggle-filenames  (cdr (assq 'last-bmenu-toggle-filenames   state))))
+  (let ((bookmark-alist  (if bmkp-bmenu-filter-function
+                             (funcall bmkp-bmenu-filter-function)
+                           bookmark-alist)))
+    (setq bmkp-latest-bookmark-alist  bookmark-alist)
+    (bookmark-bmenu-list 'filteredp)
+    (when (get-buffer bmkp-bmenu-buffer) (pop-to-buffer bmkp-bmenu-buffer))))
+
+;; Bookmark-file bookmarks.
+;;;###autoload (autoload 'bmkp-set-bookmark-file-bookmark "bookmark+")
+(defun bmkp-set-bookmark-file-bookmark (file &optional msg-p) ; Bound to `C-x x y', `C-x x c y'
+  "Create a bookmark that loads bookmark-file FILE when \"jumped\" to.
+You are prompted for the names of the bookmark file and the bookmark.
+When entering the bookmark name you can use completion against
+existing names.  This completion is lax, so you can easily edit an
+existing name.  See `bookmark-set' for particular keys available
+during this input.
+
+Non-interactively, non-nil MSG-P means display a status message."
+  (interactive
+   (list (let* ((insert-default-directory  t)
+                (std-default  (bmkp-default-bookmark-file))
+                (default      (if (bmkp-same-file-p bmkp-current-bookmark-file bmkp-last-bookmark-file)
+                                  (if (bmkp-same-file-p bmkp-current-bookmark-file std-default)
+                                      bookmark-default-file
+                                    std-default)
+                                bmkp-last-bookmark-file)))
+           (bmkp-read-bookmark-file-name "Create bookmark to load bookmark file: "
+                                         (or (file-name-directory default)  "~/")
+                                         default
+                                         'confirm)) ; Non-existing file is OK, but must confirm.
+         'MSG))
+  (setq file  (expand-file-name file))
+  (when (file-directory-p file) (error "`%s' is a directory, not a file" file))
+  (unless (file-readable-p file) (error "Unreadable bookmark file `%s'" file))
+  (with-current-buffer (let ((enable-local-variables  ())) (find-file-noselect file))
+    (goto-char (point-min))
+    (condition-case nil                 ; Check whether it's a valid bookmark file.
+        (progn (bookmark-maybe-upgrade-file-format)
+               (unless (listp (bookmark-alist-from-buffer)) (error "")))
+      (error (error "Not a valid bookmark file: `%s'" file))))
+  (let ((bookmark-make-record-function  (lexical-let ((ff  file))
+                                          (lambda () (bmkp-make-bookmark-file-record ff))))
+        (bookmark-name                  (bmkp-completing-read-lax "Bookmark-file BOOKMARK name"
+                                                                  file nil nil 'bookmark-history)))
+    (bookmark-set bookmark-name 99 'INTERACTIVEP))
+  (when msg-p (message "Set bookmark-file bookmark")))
+
+(defun bmkp-make-bookmark-file-record (bookmark-file)
+  "Create and return a bookmark-file bookmark record.
+Records the BOOKMARK-FILE name.
+Adds a handler that tests the prefix arg and loads the bookmark file
+either as a replacement for the current bookmark file or as a
+supplement to it."
+  `(,@(bookmark-make-record-default 'NO-FILE 'NO-CONTEXT nil nil 'NO-REGION)
+    (filename      . ,bookmark-file)
+    (bookmark-file . ,bookmark-file)
+    (handler       . bmkp-jump-bookmark-file)))
+
+(defun bmkp-jump-bookmark-file (bookmark &optional switchp batchp)
+  "Jump to bookmark-file bookmark BOOKMARK, which loads the bookmark file.
+Handler function for record returned by
+`bmkp-make-bookmark-file-record'.
+BOOKMARK is a bookmark name or a bookmark record.
+Non-nil optional arg SWITCHP means overwrite current bookmark list.
+Non-nil optional arg BATCHP is passed to `bookmark-load'."
+  (let ((file        (bookmark-prop-get bookmark 'bookmark-file))
+        (overwritep  (and switchp  (y-or-n-p "SWITCH to new bookmark file, instead of just adding it? "))))
+    (bookmark-load file overwritep batchp)) ; Treat load interactively, if no BATCHP.
+  ;; This `throw' is only for the case where this handler is called from `bookmark--jump-via'.
+  ;; It just tells `bookmark--jump-via' to skip the rest of what it does after calling the handler.
+  (condition-case nil
+      (throw 'bookmark--jump-via 'BOOKMARK-FILE-JUMP)
+    (no-catch nil)))
+
+;;;###autoload (autoload 'bmkp-bookmark-file-jump "bookmark+")
+(defun bmkp-bookmark-file-jump (bookmark &optional switchp no-msg) ; `C-x j y'
+  "Jump to a bookmark-file bookmark, which means load its bookmark file.
+With a prefix argument, switch to the new bookmark file.
+Otherwise, load it to supplement the current bookmark list.
+BOOKMARK is a bookmark name or a bookmark record."
+  (interactive
+   (let ((alist  (bmkp-bookmark-file-alist-only)))
+     (list (bmkp-read-bookmark-for-type "bookmark-file" alist nil nil 'bmkp-bookmark-file-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-bookmark-file-alist-only))))
+  (bmkp-jump-bookmark-file bookmark switchp no-msg))
+
+;;;###autoload (autoload 'bmkp-bookmark-file-load-jump "bookmark+")
+(defun bmkp-bookmark-file-load-jump (bookmark &optional nosavep)
+  "Prompt for a bookmark-file BOOKMARK and load that file's bookmarks.
+This adds to the current bookmark list.  It does not overwrite it.
+By default, this first saves the current bookmark list in the current
+bookmark file.  With a prefix argument it does not save first.
+BOOKMARK is a bookmark name or a bookmark record."
+  (interactive
+   (let ((alist  (bmkp-bookmark-file-alist-only)))
+     (list (bmkp-read-bookmark-for-type "bookmark-file" alist nil nil 'bmkp-bookmark-file-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-bookmark-file-alist-only))))
+  (let ((file  (bookmark-prop-get bookmark 'bookmark-file)))
+    (bookmark-load file nil (if nosavep t 'save))
+    (bmkp-refresh/rebuild-menu-list)
+    (message "Added bookmarks in `%s'" file)))
+
+;;;###autoload (autoload 'bmkp-bookmark-file-switch-jump "bookmark+")
+(defun bmkp-bookmark-file-switch-jump (bookmark &optional nosavep)
+  "Prompt for a bookmark-file BOOKMARK and switch to that bookmark file.
+Unlike `C-u \\[bmkp-bookmark-file-jump]', you are not prompted for confirmation.
+By default, this first saves the current bookmark list in the current
+bookmark file.  With a prefix argument it does not save first.
+BOOKMARK is a bookmark name or a bookmark record."
+  (interactive
+   (let ((alist  (bmkp-bookmark-file-alist-only)))
+     (list (bmkp-read-bookmark-for-type "bookmark-file" alist nil nil 'bmkp-bookmark-file-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-bookmark-file-alist-only))))
+  (let ((file  (bookmark-prop-get bookmark 'bookmark-file)))
+    (bookmark-load file t (if nosavep t 'save))
+    (bmkp-refresh/rebuild-menu-list)
+    (message "Switched to bookmarks in `%s'" file)))
+
+
+;; Snippet bookmarks
+;; Inspired by emacs-develNOSPAMgnu.org post from Masatake Yamato [yamatoNOSPAMredhat.com], 2012-01-06.
+;;;###autoload (autoload 'bmkp-set-snippet-bookmark "bookmark+")
+(defun bmkp-set-snippet-bookmark (beg end &optional promptp msgp)
+                                        ; Bound globally to `C-x x c M-w'.
+  "Save the text of the active region as a bookmark.
+The bookmark is automatically named with the first line of the region
+text.  With a prefix argument you are prompted for the name instead.
+
+Jumping to the bookmark copies the saved text to the `kill-ring', so
+you can yank it using `C-y'."
+  (interactive "r\nP\np")
+  (unless (and mark-active  transient-mark-mode) (error "No active region"))
+  (when (equal beg end) (error "Region is empty"))
+  (lexical-let ((text  (buffer-substring-no-properties beg end)))
+    (let ((bookmark-make-record-function  (lambda ()
+                                            `(,@(bookmark-make-record-default 'NO-FILE 'NO-CONTEXT)
+                                              (text    . ,text)
+                                              (handler . bmkp-jump-snippet))))
+          (bname                          (and (not promptp)  (car (split-string text "[\n]")))))
+      (bookmark-set bname 99 'INTERACTIVEP)
+      ;; `bookmark-set does the prompting, providing default names.  
+      (when msgp (message "Region text bookmarked%s" (if bname (format " as `%s'" bname) ""))))))
+
+(defun bmkp-jump-snippet (bookmark)
+  "Copy the text saved in BOOKMARK to the `kill-ring'.
+Handler for snippet bookmarks."
+  (kill-new (bookmark-prop-get bookmark 'text))
+  (message "Snippet of bookmark `%s' copied to `kill-ring'" (bmkp-bookmark-name-from-record bookmark)))
+
+;;;###autoload (autoload 'bmkp-snippet-to-kill-ring "bookmark+")
+(defun bmkp-snippet-to-kill-ring (bookmark) ; `C-x j M-w'
+  "Jump to a snippet bookmark: copy its saved text to the `kill-ring'.
+This is a specialization of `bookmark-jump' for snippet bookmarks."
+  (interactive
+   (let ((alist  (bmkp-snippet-alist-only)))
+     (list (bmkp-read-bookmark-for-type "snippet" alist nil nil 'bmkp-snippet-history nil
+                                        "Copy snippet to kill ring"))))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-snippet-alist-only))))
+  (bmkp-jump-1 bookmark 'ignore))
+
+;; Desktop bookmarks
+;;;###autoload (autoload 'bmkp-set-desktop-bookmark "bookmark+")
+(defun bmkp-set-desktop-bookmark (desktop-file &optional nosavep)
+                                        ; Bound globally to `C-x x K', `C-x r K', `C-x x c K'
+  "Save the desktop as a bookmark.
+You are prompted for the desktop-file location and the bookmark name.
+The default value for the desktop-file location is the current value
+of `desktop-base-file-name'.  As always, you can use `M-n' to retrieve
+the default value.
+
+With a prefix arg, set a bookmark to an existing desktop file - do not
+save the current desktop.  Do not overwrite the file whose name you
+enter, just use it to set the bookmark.
+
+If you also use library Icicles, then the desktop files of all
+existing desktop bookmarks are available during the desktop file-name
+completion as proxy candidates.  To see them, use `C-M-_' to turn on
+the display of proxy candidates."
+  (interactive
+   (progn (unless (condition-case nil (require 'desktop nil t) (error nil))
+            (error "You must have library `desktop.el' to use this command"))
+          (let ((icicle-proxy-candidates                     (and (boundp 'icicle-mode) icicle-mode
+                                                                  (mapcar (lambda (bmk)
+                                                                            (bookmark-prop-get
+                                                                             bmk 'desktop-file))
+                                                                          (bmkp-desktop-alist-only))))
+                (icicle-unpropertize-completion-result-flag  t))
+            (list (read-file-name
+                   (if current-prefix-arg "Use existing desktop file: " "Save desktop in file: ")
+                   bmkp-desktop-default-directory
+                   (if (boundp 'desktop-base-file-name) desktop-base-file-name desktop-basefilename)
+                   current-prefix-arg)
+                  current-prefix-arg))))
+  (unless (or nosavep  (condition-case nil (require 'desktop nil t) (error nil)))
+    (error "You must have library `desktop.el' to use this command"))
+  (unless (file-name-absolute-p desktop-file)
+    (setq desktop-file  (expand-file-name desktop-file bmkp-desktop-default-directory)))
+  (set-text-properties 0 (length desktop-file) nil desktop-file)
+  (if nosavep
+      (unless (bmkp-desktop-file-p desktop-file) (error "Not a desktop file: `%s'" desktop-file))
+    (bmkp-desktop-save desktop-file))
+  (let ((bookmark-make-record-function  (lexical-let ((df  desktop-file))
+                                          (lambda () (bmkp-make-desktop-record df))))
+        (current-prefix-arg             99)) ; Use all bookmarks for completion, for `bookmark-set'.
+    (call-interactively #'bookmark-set)))
+
+(defun bmkp-desktop-save (desktop-file)
+  "Save current desktop in DESKTOP-FILE."
+  (let ((desktop-basefilename     (file-name-nondirectory desktop-file)) ; Emacs < 22
+        (desktop-base-file-name   (file-name-nondirectory desktop-file)) ; Emacs 23+
+        (desktop-dir              (file-name-directory desktop-file))
+        (desktop-restore-eager    t)    ; Don't bother with lazy restore.
+        (desktop-globals-to-save  (bmkp-remove-if (lambda (elt) (memq elt bmkp-desktop-no-save-vars))
+                                                  desktop-globals-to-save)))
+    (cond ((< emacs-major-version 22)   ; Emacs 22 introduced `RELEASE' (locking).
+           (desktop-save desktop-dir))
+          ((or (< emacs-major-version 24)  (and (= emacs-major-version 24)  (< emacs-minor-version 4)))
+           (desktop-save desktop-dir 'RELEASE))
+          (t                            ; Emacs 24.4 introduced `AUTOSAVE'.
+           (desktop-save desktop-dir 'RELEASE 'AUTOSAVE)))
+    (message "Desktop saved in `%s'" desktop-file)))
+
+(unless (fboundp 'desktop-full-file-name) ; Emacs < 22.  (This is the vanilla definition.)
+  (defun desktop-full-file-name (&optional dirname)
+    "Return the full name of the desktop file in DIRNAME.
+DIRNAME omitted or nil means use `desktop-dirname'."
+    (expand-file-name desktop-basefilename (or dirname  desktop-dirname))))
+
+(defun bmkp-desktop-save-as-last ()
+  "Save desktop to the file that is the value of `bmkp-desktop-current-file'.
+Do nothing if any of these are true:
+
+ * `desktop-save-mode' is non-nil
+ * `bmkp-desktop-current-file' is nil
+ * `bmkp-desktop-current-file' does not seem to be current (a non-bookmark
+   desktop was last made current)
+
+You might want to use this on `kill-emacs-hook'."
+  (when (and (not desktop-save-mode)  bmkp-desktop-current-file
+             (bmkp-same-file-p (desktop-full-file-name) bmkp-desktop-current-file))
+    (bmkp-desktop-save bmkp-desktop-current-file)))
+
+;;; (defun bmkp-desktop-file-p (file)
+;;;   "Return non-nil if FILE is readable and appears to be a desktop file.
+;;; FILE is a file-name string."
+;;;   (and (stringp file)
+;;;        (file-readable-p file)
+;;;        (with-current-buffer (let ((enable-local-variables nil)) (find-file-noselect file))
+;;;          (goto-char (point-min))
+;;;          (and (zerop (forward-line 2))
+;;;               (bmkp-looking-at-p "^;; Desktop File for Emacs$")))))
+
+;; Similar to `icicle-file-desktop-p' in `icicles-fn.el'.
+;; This is better than using `find-file-noselect', which visits the file and leaves its buffer.
+(defun bmkp-desktop-file-p (filename)
+  "Return non-nil if FILENAME names a desktop file."
+  (when (consp filename) (setq filename  (car filename)))
+  (and (stringp filename)
+       (file-readable-p filename)
+       (not (file-directory-p filename))
+       (with-temp-buffer
+         (insert-file-contents-literally filename nil 0 1000)
+         (goto-char (point-min))
+         (and (zerop (forward-line 2))
+              (bmkp-looking-at-p "^;; Desktop File for Emacs"))))) ; No $, because maybe eol chars (e.g. ^M).
+
+(defun bmkp-make-desktop-record (desktop-file)
+  "Create and return a desktop bookmark record.
+DESKTOP-FILE is the absolute file name of the desktop file to use."
+  `(,@(bookmark-make-record-default 'NO-FILE 'NO-CONTEXT nil nil 'NO-REGION)
+    (filename     . ,bmkp-non-file-filename)
+    (desktop-file . ,desktop-file)
+    (handler      . bmkp-jump-desktop)))
+
+(defun bmkp-jump-desktop (bookmark)
+  "Jump to desktop bookmark BOOKMARK.
+Handler function for record returned by `bmkp-make-desktop-record'.
+BOOKMARK is a bookmark name or a bookmark record."
+  (let ((desktop-file  (bookmark-prop-get bookmark 'desktop-file)))
+    (unless (condition-case nil (require 'desktop nil t) (error nil))
+      (error "You must have library `desktop.el' to use this command"))
+    ;; (unless desktop-file (error "Not a desktop-bookmark: %S" bookmark)) ; Shouldn't happen.
+    (bmkp-desktop-change-dir desktop-file)
+    (unless (bmkp-desktop-read desktop-file) (error "Could not load desktop file"))))
+
+;; Derived from code in `desktop-change-dir'.
+;;;###autoload (autoload 'bmkp-desktop-change-dir "bookmark+")
+(defun bmkp-desktop-change-dir (desktop-file)
+  "Change to desktop saved in DESKTOP-FILE.
+Kill the desktop as specified by variables `desktop-save-mode' and
+ `desktop-save' (starting with Emacs 22).
+Clear the desktop and load DESKTOP-FILE."
+  (interactive
+   (progn (unless (condition-case nil (require 'desktop nil t) (error nil))
+            (error "You must have library `desktop.el' to use this command"))
+          (list (let ((icicle-unpropertize-completion-result-flag  t))
+                  (read-file-name "Change to desktop file: " bmkp-desktop-default-directory)))))
+  (unless (condition-case nil (require 'desktop nil t) (error nil))
+    (error "You must have library `desktop.el' to use this command"))
+  (unless (file-name-absolute-p desktop-file)
+    (setq desktop-file  (expand-file-name desktop-file bmkp-desktop-default-directory)))
+  (set-text-properties 0 (length desktop-file) nil desktop-file)
+  (let ((desktop-basefilename     (file-name-nondirectory desktop-file)) ; Emacs < 22
+        (desktop-base-file-name   (file-name-nondirectory desktop-file)) ; Emacs 23+
+        (desktop-dir              (file-name-directory desktop-file))
+        (desktop-restore-eager    t)    ; Don't bother with lazy restore.
+        (desktop-globals-to-save  (bmkp-remove-if (lambda (elt) (memq elt bmkp-desktop-no-save-vars))
+                                                  desktop-globals-to-save)))
+    (bmkp-desktop-kill)
+    (desktop-clear)
+    (if (< emacs-major-version 22) (desktop-read) (desktop-read desktop-dir))))
+
+;; Derived from code in `desktop-kill'.
+(defun bmkp-desktop-kill ()
+  "If `desktop-save-mode' is non-nil, do what `desktop-save' says to do.
+In any case, release the lock on the desktop file.
+This function does nothing in Emacs versions prior to Emacs 22."
+  ;; We assume here: `desktop.el' has been loaded and `desktop-dirname' is defined.
+  (when (and (boundp 'desktop-save-mode) ; Not defined in Emacs 20-21.
+             desktop-save-mode
+             (let ((exists  (file-exists-p (desktop-full-file-name))))
+               (or (eq desktop-save t)
+                   (and exists  (memq desktop-save '(ask-if-new if-exists)))
+                   (and (or (memq desktop-save '(ask ask-if-new))
+                            (and exists  (eq desktop-save 'ask-if-exists)))
+                        (y-or-n-p "Save current desktop first? ")))))
+    (condition-case err
+        (if (or (< emacs-major-version 24)
+                (and (= emacs-major-version 24)  (< emacs-minor-version 4)))
+            (desktop-save desktop-dirname 'RELEASE)
+          (desktop-save desktop-dirname 'RELEASE 'AUTOSAVE)) ; Emacs 24.4 introduced `AUTOSAVE'.
+      (file-error (unless (yes-or-no-p "Error while saving the desktop.  IGNORE? ")
+                    (signal (car err) (cdr err))))))
+  ;; Just release lock, regardless of whether this Emacs process is the owner.
+  (when (fboundp 'desktop-release-lock) (desktop-release-lock))) ; Not defined for Emacs 20.
+
+;; Derived from code in `desktop-read'.
+;;;###autoload (autoload 'bmkp-desktop-read "bookmark+")
+(defun bmkp-desktop-read (file)
+  "Load desktop-file FILE, then run `desktop-after-read-hook'.
+Return t if FILE was loaded, nil otherwise."
+  (interactive)
+  (unless (file-name-absolute-p file) ; Should never happen.
+    (setq file  (expand-file-name file bmkp-desktop-default-directory)))
+  (when (file-directory-p file) (error "`%s' is a directory, not a file" file))
+  (setq desktop-dirname  (file-name-directory file))
+  (if (not (file-readable-p file))
+      nil                               ; Return nil, meaning not loaded.
+    (let ((desktop-restore-eager      t) ; Don't bother with lazy restore.
+          (desktop-first-buffer       nil)
+          (desktop-buffer-ok-count    0)
+          (desktop-buffer-fail-count  0)
+          (desktop-save               nil)) ; Prevent desktop saving during eval of desktop buffer.
+      (when (fboundp 'desktop-lazy-abort) (desktop-lazy-abort)) ; Emacs 22+.
+      (load file t t t)
+      (when (boundp 'desktop-file-modtime) ; Emacs 22+
+        (setq desktop-file-modtime  (nth 5 (file-attributes file))))
+      ;; `desktop-create-buffer' puts buffers at end of the buffer list.
+      ;; We want buffers existing prior to evaluating the desktop (and not reused) to be placed
+      ;; at the end of the buffer list, so we move them here.
+      (mapc 'bury-buffer (nreverse (cdr (memq desktop-first-buffer (nreverse (buffer-list))))))
+      (bmkp--pop-to-buffer-same-window (car (buffer-list)))
+      (run-hooks 'desktop-delay-hook)
+      (setq desktop-delay-hook  ())
+      (run-hooks 'desktop-after-read-hook)
+      (when (boundp 'desktop-buffer-ok-count) ; Emacs 22+
+        (message "Desktop: %d buffer%s restored%s%s." desktop-buffer-ok-count
+                 (if (= 1 desktop-buffer-ok-count) "" "s")
+                 (if (< 0 desktop-buffer-fail-count)
+                     (format ", %d failed to restore" desktop-buffer-fail-count)
+                   "")
+                 (if (and (boundp 'desktop-buffer-args-list)  desktop-buffer-args-list)
+                     (format ", %d to be restored lazily" (length desktop-buffer-args-list))
+                   "")))
+      t)))                              ; Return t, meaning successfully loaded.
+
+;;;###autoload (autoload 'bmkp-desktop-delete "bookmark+")
+(defun bmkp-desktop-delete (bookmark)
+  "Delete desktop bookmark BOOKMARK, and delete its desktop file.
+Release the lock file in that desktop's directory.
+\(This means that if you currently have locked a different desktop
+in the same directory, then you will need to relock it.)
+BOOKMARK is a bookmark name or a bookmark record."
+  (interactive
+   (let ((alist  (bmkp-desktop-alist-only)))
+     (list (bmkp-read-bookmark-for-type "desktop" alist nil nil 'bmkp-desktop-history "Delete "))))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-desktop-alist-only))))
+  (let ((desktop-file  (bookmark-prop-get bookmark 'desktop-file)))
+    (unless desktop-file (error "Not a desktop-bookmark: `%s'" bookmark))
+    ;; Release the desktop lock file in the same directory as DESKTOP-FILE.
+    ;; This will NOT be the right thing to do if a desktop file different from DESKTOP-FILE
+    ;; is currently locked in the same directory.
+    (let ((desktop-dir  (file-name-directory desktop-file)))
+      (when (fboundp 'desktop-release-lock) (desktop-release-lock))) ; Not defined for Emacs 20.
+    (when (file-exists-p desktop-file) (delete-file desktop-file)))
+  (bookmark-delete bookmark))
+
+;; Icicle search-hits bookmarks
+(defun bmkp-jump-icicle-search-hits (bookmark)
+  "Handle an Icicles search-hits bookmark BOOKMARK."
+  (unless (and (boundp 'icicle-mode)  icicle-mode  (icicle-completing-p)
+               (condition-case nil (icicle-barf-if-outside-Completions-and-minibuffer) (error nil)))
+    (error "You can use this bookmark only in Icicle mode, and only during completion"))
+  (let ((raw-cands  (bookmark-prop-get bookmark 'hits)))
+    (setq icicle-saved-completion-candidates
+          (if icicle-multi-completing-p
+              raw-cands                 ; But will not work if RAW-CANDS are not multi-completions.
+            (mapcar #'icicle-transform-multi-completion raw-cands)))
+    (if bmkp-icicles-search-hits-retrieve-more
+        (icicle-candidate-set-retrieve-more)
+      (icicle-candidate-set-retrieve))))
+
+;;;###autoload (autoload 'bmkp-retrieve-icicle-search-hits "bookmark+")
+(defun bmkp-retrieve-icicle-search-hits () ; Bound to `C-x C-M-<' during Icicles completion.
+  "Replace the current set of Icicles search hits by those from a bookmark.
+You are prompted for the bookmark name.
+This makes sense only if the buffer(s) or file(s) currently being
+searched correspond to the recorded search hits."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  (bmkp-retrieve-icicle-search-hits-1))
+
+;;;###autoload (autoload 'bmkp-retrieve-more-icicle-search-hits "bookmark+")
+(defun bmkp-retrieve-more-icicle-search-hits () ; Bound to `C-x C-<' during Icicles completion.
+  "Add the Icicles search hits from a bookmark to the current set of hits.
+You are prompted for the bookmark name.
+This makes sense only if the buffer(s) or file(s) currently being
+searched correspond to the recorded search hits."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  (bmkp-retrieve-icicle-search-hits-1 'MORE))
+
+(defun bmkp-retrieve-icicle-search-hits-1 (&optional morep)
+  "Helper for `bmkp-retrieve-(more-)icicle-search-hits'."
+  (unless (and (boundp 'icicle-searching-p)  icicle-searching-p)
+    (error "This command can be used only during Icicles search"))
+  (let* ((hits-bmks  (bmkp-icicles-search-hits-alist-only))
+         (bmk        (let ((icicle-completion-candidates
+                            icicle-completion-candidates)
+                           (enable-recursive-minibuffers  t))
+                       (bookmark-completing-read "Bookmark name"
+                                                 (mapcar #'bmkp-bookmark-name-from-record hits-bmks)
+                                                 hits-bmks
+                                                 nil
+                                                 nil
+                                                 'USE-NIL-ALIST-P)))
+         (bmkp-icicles-search-hits-retrieve-more  morep))
+    (bookmark-jump bmk)))
+
+;;;###autoload (autoload 'bmkp-set-icicle-search-hits-bookmark "bookmark+")
+(defun bmkp-set-icicle-search-hits-bookmark () ; Bound to `C-x C-M->' during Icicles completion.
+  "Record the current set of Icicles search-hit candidates as a bookmark."
+  (interactive)
+  (unless (and (boundp 'icicle-searching-p)  icicle-searching-p)
+    (error "This command can be used only during Icicles search"))
+  (unless icicle-completion-candidates (error "No search hits to record"))
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  (let ((bookmark-make-record-function  'bmkp-make-icicle-search-hits-record)
+        (enable-recursive-minibuffers   t))
+    (call-interactively #'bookmark-set)))
+
+(defun bmkp-make-icicle-search-hits-record ()
+  "Create and return an Icicles search-hits bookmark record."
+  `(,@(bookmark-make-record-default 'NO-FILE 'NO-CONTEXT nil nil 'NO-REGION)
+      (filename    . ,bmkp-non-file-filename)
+      (hits        . ,(mapcar #'bmkp-unpropertized-string icicle-completion-candidates))
+      (handler     . bmkp-jump-icicle-search-hits)))
+
+;; Variable-list bookmarks
+(when (boundp 'zz-izones-var)           ; In `zones.el'.
+  (defun bmkp-set-izones-bookmark (&optional variable msgp)
+    "Save a ring of buffer zones as a bookmark.
+The zones can use markers or readable-marker objects for any
+buffers.  You need library `zones.el' to use the bookmark created.
+
+By default, the zones are those defined by the variable that is the
+current value of `zz-izones-var', which defaults to `zz-izones'.  With
+a prefix arg you are prompted for a different variable to use.
+
+Non-interactively, VARIABLE is the restrictions variable to use."
+    (interactive (let ((var  (or (and current-prefix-arg  (zz-read-any-variable "Variable: " zz-izones-var))
+                                 zz-izones-var)))
+                   (list var t)))
+    (unless variable (setq variable  zz-izones-var))
+    (let ((bookmark-make-record-function
+           (lambda ()
+             (bmkp-make-variable-list-record
+              `((,variable              ; Format: (NUM BEGM ENDM), BEGM and ENDM are readable-marker objects.
+                 . ,(mapcar (lambda (xx)
+                              (let ((id     (nth 0 xx))
+                                    (beg    (nth 1 xx))
+                                    (end    (nth 2 xx))
+                                    (extra  (nthcdr 3 xx)))
+                                `(,id ,(zz-readable-marker beg) ,(zz-readable-marker end) ,@extra)))
+                            (symbol-value variable))))))))
+      (call-interactively #'bookmark-set)
+      (when (and msgp  (not (featurep 'zones))
+                 (message "Bookmark created, but you need `zones.el' to use it")))))
+
+  )
+
+;;;###autoload (autoload 'bmkp-wrap-bookmark-with-last-kbd-macro "bookmark+")
+(defun bmkp-wrap-bookmark-with-last-kbd-macro (sequence bookmark &optional arg msgp)
+                                        ; Bound globally to `C-x x C-k'.
+  "Return a SEQUENCE bookmark that invokes BOOKMARK plus `last-kbd-macro'.
+If bookmark SEQUENCE does not yet exist, create it.  Else, update it.
+You are prompted for the SEQUENCE and BOOKMARK names.
+
+BOOKMARK can be any kind of bookmark.  A special case is when it is a
+sequence bookmark:
+
+ * If BOOKMARK is the same as SEQUENCE and is an existing sequence
+   bookmark then it is updated only by appending the keyboard macro to
+   the sequence.
+
+ * If BOOKMARK is a sequence bookmark different from SEQUENCE then
+   SEQUENCE is updated to invoke the sequence in BOOKMARK plus
+   `last-kbd-macro' either before or after the other bookmarks of
+   SEQUENCE, according to the prefix arg, which is passed to
+   `bmkp-set-sequence-bookmark'."
+  (interactive (list (bmkp-completing-read-lax "Sequence bookmark" (bmkp-new-bookmark-default-names))
+                     (bmkp-completing-read-lax "Bookmark" (bmkp-new-bookmark-default-names))
+                     current-prefix-arg
+                     'MSGP))
+  (unless last-kbd-macro (error "No keyboard macro defined"))
+  (let ((kbd-macro-vec  (read-kbd-macro (format-kbd-macro last-kbd-macro) 'VECTOR)))
+    (bmkp-set-sequence-bookmark sequence (if (equal bookmark sequence)
+                                             (list kbd-macro-vec)
+                                           (list bookmark kbd-macro-vec))
+                                arg msgp)))
+
+;; Not used yet.
+(defun bmkp-pop-to-readable-marker (readable-marker)
+  "Go to the marker recorded as persistent READABLE-MARKER.
+The form of the input is (marker MARKER-BUFFER MARKER-POSITION."
+  (pop-to-buffer (cadr readable-marker))
+  (goto-char (cadr (cdr readable-marker))))
+
+;;;###autoload (autoload 'bmkp-set-sequence-bookmark "bookmark+")
+(defun bmkp-set-sequence-bookmark (seqname bookmark-names &optional arg msgp)
+                                        ; Bound globally to `C-x x c s'.
+  "Create or update a sequence bookmark named SEQNAME from BOOKMARK-NAMES.
+If a sequence bookmark named SEQNAME does not exist then create one.
+Else act on the existing bookmarks in bookmark SEQNAME as follows:
+
+ * no prefix arg:    Append BOOKMARK-NAMES to those present.
+ * prefix arg < 0:   Replace those present with BOOKMARK-NAMES.
+ * other prefix arg: Prepend BOOKMARK-NAMES to those present.
+
+You are prompted for SEQNAME and each of the BOOKMARK-NAMES.
+
+When entering each item of BOOKMARK-NAMES you can enter an existing or
+future bookmark name, or you can enter the name of a function or a
+named keyboard macro (provided what you type does not match a bookmark
+name).  If a function or keyboard macro, then a function bookmark is
+created for it and that bookmark is included in the sequence.
+
+When the sequence bookmark is invoked (\"jumped to\"), its bookmarks
+are invoked in order.  In particular, any given bookmark is invoked
+once for each of its occurrences in the sequence.
+
+From Lisp code:
+
+BOOKMARK-NAMES is generally a list of bookmarks or bookmark names
+ \(strings).
+
+ Each item in BOOKMARK-NAMES can alternatively be one of the
+ following, in which case a function bookmark is created for it and is
+ used in the sequence.
+
+  * a keyboard macro as a vector
+  * a function, which includes a lambda form or a symbol whose
+    function value is a function or a keyboard macro.
+
+ If an item in BOOKMARK-NAMES is a sequence bookmark then its
+ bookmarks are used as if they were items of BOOKMARK-NAMES.
+
+MSGP non-nil means possibly interact with the user, showing messages."
+  (interactive (list
+                (if (< (prefix-numeric-value current-prefix-arg) 0)
+                    (bookmark-completing-read "Replace existing sequence bookmark"
+                                              nil
+                                              (bmkp-sequence-alist-only)
+                                              nil
+                                              nil
+                                              'USE-NIL-ALIST-P)
+                  (bmkp-completing-read-lax "Create or update sequence bookmark"
+                                            (bmkp-new-bookmark-default-names)
+                                            (bmkp-sequence-alist-only)))
+                (bmkp-completing-read-bookmarks nil nil nil 'lax)
+                current-prefix-arg
+                'MSGP))
+  (let* ((seq        (bmkp-get-bookmark-in-alist seqname 'NOERROR))
+         (exists     (and seq  (bmkp-sequence-bookmark-p seq)))
+         (replacing  t)
+         (bnames     ())
+         fun)
+    (dolist (bname  bookmark-names)
+      (cond ((or (functionp (setq fun bname)) ; Function from Lisp.
+                 (vectorp fun)          ; Keyboard macro.
+                 (functionp (setq fun  (condition-case nil ; Function name from user
+                                           (bmkp-read-from-whole-string bname)
+                                         (error nil)))))
+             (let ((fun-bmk-name
+                    (cond ((symbolp fun) (symbol-name fun)) ; Named function.  Use its name.
+                          ((vectorp fun) (format-kbd-macro fun)) ; Keyboard macro.  Use human-readable strg
+                          ;; Lambda form.  Use as much as possible, but uniquify (no such symbol name).
+                          (t (let ((ii     1)
+                                   (len    (length bname))
+                                   (trial  (make-string (1+ bmkp-bookmark-name-length-max) 88)))
+                               (while (and (< ii len)  (> (length trial) bmkp-bookmark-name-length-max))
+                                 (setq trial  (make-temp-name (substring bname 0 (- ii)))))
+                               (while (intern-soft
+                                       (setq trial  (make-temp-name (substring bname 0 (- ii))))))
+                               trial)))))
+               (push (bmkp-bookmark-name-from-record (bmkp-make-function-bookmark fun-bmk-name fun))
+                     bnames)))
+            ((bmkp-sequence-bookmark-p bname) ; Sequence bookmark.
+             (setq bnames (append (reverse (bookmark-prop-get bname 'sequence)) bnames)))
+            ((stringp bname) (push bname bnames)) ; Bookmark name.
+            ((bmkp-get-bookmark bname 'NOERROR) ; Full bookmark.
+             (push (bmkp-bookmark-name-from-record bname) bnames))
+            (t (error "Bad BOOKMARK-NAMES arg to `bmkp-set-sequence-bookmark': `%S'"
+                      bookmark-names)))) ; Punt.
+    (setq bnames  (nreverse bnames))
+    (if (not exists)
+        (when msgp (message "Creating sequence bookmark..."))
+      (if (< (prefix-numeric-value arg) 0)
+          (when msgp (message "REPLACING existing sequence bookmark...") (sit-for 0.5))
+        (when msgp (message "%sing to sequence bookmark..." (if arg "Prepend" "Append")) (sit-for 0.5))
+        (setq replacing  nil
+              bnames     (if arg
+                             (nconc bnames (bookmark-prop-get seq 'sequence))
+                           (nconc (bookmark-prop-get seq 'sequence) bnames)))))
+    (let ((bookmark-make-record-function `(lambda () (bmkp-make-sequence-record ',bnames))))
+      (bookmark-set seqname))
+    (when msgp (message "Sequence `%s' %s" seqname (if exists
+                                                       (if replacing "replaced" "updated")
+                                                     "created")))))
+
+(defun bmkp-make-sequence-record (bookmark-names)
+  "Create and return a sequence bookmark record.
+BOOKMARK-NAMES is a list of names of the bookmarks to be invoked in
+sequence."
+  (let ((record  `(,@(bookmark-make-record-default 'NO-FILE 'NO-CONTEXT 0 nil 'NO-REGION)
+                   (sequence . ,bookmark-names)
+                   (handler  . bmkp-jump-sequence))))
+    record))
+
+(when (require 'kmacro nil t)           ; Emacs 22+
+
+  (defun bmkp-set-kmacro-bookmark (bookmark-name keyboard-macro &optional msg-p)
+    "Create a function bookmark named BOOKMARK-NAME from KEYBOARD-MACRO.
+Prompt for BOOKMARK-NAME and the name of the keyboard macro to use.
+With a prefix arg, use `last-kbd-macro' as the keyboard macro."
+    (interactive
+     (let ((bname  (bmkp-completing-read-lax "Bookmark"))
+           (kmac   (if current-prefix-arg
+                       last-kbd-macro
+                     (symbol-function (intern (completing-read "Keyboard macro name: "
+                                                               obarray
+                                                               (lambda (elt)
+                                                                 (and (fboundp elt)
+                                                                      (or (stringp (symbol-function elt))
+                                                                          (vectorp (symbol-function elt))
+                                                                          (get elt 'kmacro))))
+                                                               t))))))
+       (list bname kmac 'MSG)))
+    (let* ((bmk     (bmkp-get-bookmark-in-alist bookmark-name 'NOERROR))
+           (exists  (and bmk  (bmkp-function-bookmark-p bmk))))
+      (bmkp-make-function-bookmark bookmark-name keyboard-macro msg-p)
+      (when msg-p
+        (message "Function bookmark `%s' %s" bookmark-name (if exists "replaced" "created")))))
+
+  (defun bmkp-set-kmacro-list-bookmark (bookmark-name)
+    "Save all current keyboard macros as a kmacro-list bookmark."
+    (interactive (list (bmkp-completing-read-lax "Bookmark")))
+    (let ((bookmark-make-record-function  (lambda ()
+                                            (bmkp-make-kmacro-list-record
+                                             (cons (kmacro-ring-head) kmacro-ring)))))
+      (bookmark-set bookmark-name)))
+
+  (defun bmkp-make-kmacro-list-record (kmacros)
+    "Create and return a kmacro-list bookmark record.
+KMACROS is the list of kmacros to save.  It has the same form as
+`kmacro-ring'.
+
+Each entry in KMACROS thus has the form (MACRO COUNTER FORMAT)."
+    (let ((record  `(,@(bookmark-make-record-default 'NO-FILE 'NO-CONTEXT nil nil 'NO-REGION)
+                     (kmacros      . ,kmacros)
+                     (handler      . bmkp-jump-kmacro-list))))
+      record))
+
+  )
+
+;;;###autoload (autoload 'bmkp-set-variable-list-bookmark "bookmark+")
+(defun bmkp-set-variable-list-bookmark (variables)
+  "Save a list of variables as a bookmark.
+Interactively, read the variables to save, using
+`bmkp-read-variables-completing'."
+  (interactive (list (bmkp-read-variables-completing)))
+  (let ((bookmark-make-record-function  (lexical-let ((vars  variables))
+                                          (lambda () (bmkp-make-variable-list-record vars)))))
+    (call-interactively #'bookmark-set)))
+
+;; Not used in the Bookmark+ code.  Available for users to create varlist bookmark non-interactively.
+(defun bmkp-create-variable-list-bookmark (bookmark-name vars vals &optional buffer-name)
+  "Create a variable-list bookmark named BOOKMARK-NAME from VARS and VALS.
+VARS and VALS are corresponding lists of variables and their values.
+
+Optional arg BUFFER-NAME is the buffer name to use for the bookmark (a
+string).  This is useful if some of the variables are buffer-local.
+If BUFFER-NAME is nil, the current buffer name is recorded."
+  (eval `(multiple-value-bind ,vars ',vals
+          (let ((bookmark-make-record-function  (lexical-let ((vs   vars)
+                                                              (buf  buffer-name))
+                                                  (lambda () (bmkp-make-variable-list-record vs buf)))))
+            (bookmark-set ,bookmark-name)))))
+
+(defun bmkp-read-variables-completing (&optional option)
+  "Read variable names with completion, and return them as a list of symbols.
+Reads names one by one, until you hit `RET' twice consecutively.
+Non-nil argument OPTION means read only user option names."
+  (bookmark-maybe-load-default-file)
+  (let ((var   (bmkp-read-variable "Variable (RET for each, empty input to finish): " option))
+        (vars  ())
+        old-var)
+    (while (not (string= "" var))
+      (add-to-list 'vars var)
+      (setq var  (bmkp-read-variable "Variable: " option)))
+    (nreverse vars)))
+
+(defun bmkp-read-variable (prompt &optional option default-value)
+  "Read name of a variable and return it as a symbol.
+Prompt with string PROMPT.
+With non-nil OPTION, read the name of a user option.
+The default value is DEFAULT-VALUE if non-nil, or the nearest symbol
+to the cursor if it is a variable."
+  (setq option  (if option 'user-variable-p 'boundp))
+  (let ((symb                                        (cond ((fboundp 'symbol-nearest-point)
+                                                            (symbol-nearest-point)) ; In `thingatpt+.el'.
+                                                           ((fboundp 'symbol-at-point) (symbol-at-point))
+                                                           (t nil)))
+        (enable-recursive-minibuffers                t)
+        (icicle-unpropertize-completion-result-flag  t))
+    (when (and default-value  (symbolp default-value))
+      (setq default-value  (symbol-name default-value)))
+    (intern (completing-read prompt obarray option t nil 'minibuffer-history
+                             (or default-value  (and (funcall option symb)  (symbol-name symb)))
+                             t))))
+
+(defun bmkp-make-variable-list-record (variables &optional buffer-name)
+  "Create and return a variable-list bookmark record.
+VARIABLES is the list of variables to save.
+Each entry in VARIABLES is either a variable (a symbol) or a cons
+ whose car is a variable and whose cdr is the variable's value.
+
+Optional arg BUFFER-NAME is the buffer to use for the bookmark.  This
+is useful if some of the variables are buffer-local.  If BUFFER-NAME
+is nil, the current buffer is used."
+  (let ((record  `(,@(bookmark-make-record-default 'NO-FILE 'NO-CONTEXT nil nil 'NO-REGION)
+                   (filename     . ,bmkp-non-file-filename)
+                   (variables    . ,(or (bmkp-printable-vars+vals variables)
+                                        (error "No variables to bookmark")))
+                   (handler      . bmkp-jump-variable-list))))
+    (when buffer-name  (let ((bname  (assq 'buffer-name record)))  (setcdr bname buffer-name)))
+    record))
+
+(defun bmkp-printable-vars+vals (variables)
+  "Return an alist of printable VARIABLES paired with their values.
+Display a message for any variables that are not printable.
+VARIABLES is the list of variables.  Each entry in VARIABLES is either
+ a variable (a symbol) or a cons whose car is a variable and whose cdr
+ is the variable's value."
+  (let ((vars+vals     ())
+        (unprintables  ()))
+    (dolist (var  variables)
+      (let ((val  (if (consp var) (cdr var) (symbol-value var))))
+        (if (bmkp-readable-p val)
+            (add-to-list 'vars+vals (if (consp var) var (cons var val)))
+          (add-to-list 'unprintables var))))
+    (when unprintables (message "Unsavable (unreadable) vars: %S" unprintables)  (sit-for 3))
+    vars+vals))
+
+;; Same as `savehist-printable' in `savehist-20+.el', except added `print-circle' and `print-gensym' bindings.
+(defun bmkp-readable-p (value)
+  "Return non-nil if VALUE is Lisp-readable if printed using `prin1'."
+  (cond ((numberp value))
+        ((symbolp value))
+        ((and (stringp value)           ; String with no text properties.
+              (if (fboundp 'equal-including-properties) ; Emacs 22+.
+                  (equal-including-properties value (substring-no-properties value))
+                (and (null (text-properties-at 0 value))
+                     (= 0 (next-property-change 0 value))))))
+        (t (with-temp-buffer
+             (condition-case nil
+                 (let ((print-readably  t)
+                       (print-level     nil)
+                       (print-circle    bmkp-propertize-bookmark-names-flag)
+                       (print-gensym    bmkp-propertize-bookmark-names-flag))
+                   (prin1 value (current-buffer)) ; Print value into a buffer and try to read back.
+                   (read (point-min-marker))
+                   t)
+               (error nil))))))         ; Could not print and read back.
+
+(when (require 'kmacro nil t)           ; Emacs 22
+
+  (defun bmkp-jump-kmacro-list (bookmark)
+    "Jump to kmacro-list bookmark BOOKMARK, restoring the keyboard macros.
+Handler function for record returned by
+`bmkp-make-kmacro-list-record'.
+BOOKMARK is a bookmark name or a bookmark record."
+    (let ((buf       (bmkp-get-buffer-name bookmark))
+          (kbd-macs  (bookmark-prop-get bookmark 'kmacros)))
+      (unless (and buf  (get-buffer buf))
+        (message "Bookmarked for non-existent buffer `%s', so using current buffer" buf) (sit-for 3)
+        (setq buf (current-buffer)))
+      (with-current-buffer buf
+        (let ((kmacs  kbd-macs))
+          (when last-kbd-macro
+            (kmacro-push-ring (list last-kbd-macro kmacro-counter kmacro-counter-format-start)))
+          (kmacro-split-ring-element (pop kmacs))
+          (dolist (kmac  kmacs) (kmacro-push-ring kmac))))
+      (message "Keyboard macros restored in buffer `%s': %S" buf (mapcar #'car kbd-macs))
+      (sit-for 3)))
+
+  )
+
+
+;; REPLACES ORIGINAL in `info.el':
+;;
+;; Respect `Info-bookmark-use-only-node-not-file-flag'.
+;;
+;; This code and the definition of `Info-bookmark-use-only-node-not-file-flag' are also in `info+.el',
+;; so that their feature is available if you use either `Info+' or `Bookmark+'.
+;;
+;; Note: This function name doesn't respect the naming convention for bookmark handler functions.
+;;       This name gives the impression that this is a jump command.
+;;
+;;;###autoload (autoload 'Info-bookmark-jump "bookmark+")
+(defun Info-bookmark-jump (bookmark)
+  "Handler function for record returned by `Info-bookmark-make-record'.
+BOOKMARK is a bookmark name or a bookmark record.
+
+If `Info-bookmark-use-only-node-not-file-flag' is nil, and the
+recorded Info file is readable, then use it.  If not, then go to the
+recorded Info node in the manual for the current Emacs version."
+  (require 'info) ; Needed only for Emacs 20-22: not autoloaded for `Info-find-node'.
+  (let* ((absfile    (bookmark-prop-get bookmark 'filename))
+         (file       (if (or Info-bookmark-use-only-node-not-file-flag  (not (file-readable-p absfile)))
+                         (file-name-nondirectory absfile)
+                       absfile))
+         (info-node  (bookmark-prop-get bookmark 'info-node))
+         (buf        (save-window-excursion ; Vanilla FIXME: doesn't work with frames!
+                       (Info-find-node file info-node) (current-buffer))))
+    (bookmark-default-handler `("" (buffer . ,buf) . ,(bookmark-get-bookmark-record bookmark)))))
+
+(defun bmkp-jump-variable-list (bookmark)
+  "Jump to variable-list bookmark BOOKMARK, restoring the recorded values.
+Handler function for record returned by
+`bmkp-make-variable-list-record'.
+BOOKMARK is a bookmark name or a bookmark record."
+  (let ((buf        (bmkp-get-buffer-name bookmark))
+        (vars+vals  (bookmark-prop-get bookmark 'variables)))
+    (unless (get-buffer buf)
+      (message "Bookmarked for non-existent buffer `%s', so using current buffer" buf) (sit-for 3)
+      (setq buf (current-buffer)))
+    (with-current-buffer buf
+      (dolist (var+val  vars+vals)
+        (set (car var+val)  (cdr var+val))))
+    (message "Variables restored in buffer `%s': %S" buf (mapcar #'car vars+vals))
+    (sit-for 3)))
+
+;; URL browse support
+(defun bmkp-make-url-browse-record (url)
+  "Create and return a url bookmark for `browse-url' to visit URL.
+The handler is `bmkp-jump-url-browse'."
+  (require 'browse-url)
+  (let ((url-0  (copy-sequence url)))
+    (set-text-properties 0 (length url) () url-0)
+    `((filename . ,bmkp-non-file-filename)
+      (location . ,url-0)
+      (handler  . bmkp-jump-url-browse))))
+
+(defun bmkp-jump-url-browse (bookmark)
+  "Handler function for record returned by `bmkp-make-url-browse-record'.
+BOOKMARK is a bookmark name or a bookmark record."
+  (require 'browse-url)
+  (let ((url  (bookmark-prop-get bookmark 'location)))
+    (browse-url url)))
+
+
+;; EWW support
+(when (> emacs-major-version 24)        ; Emacs 25+
+
+  ;; This is set by `bmkp-eww-rename-buffer' and used in `bmkp-jump-eww' for local var `after-render-function'.
+  (defvar bmkp-eww-new-buf-name nil
+    "If non-nil, the name of the EWW buffer to jump to.")
+  (make-variable-buffer-local 'bmkp-eww-new-buf-name)
+
+  ;; This is set by `bmkp-jump-eww' and used in `bmkp-eww-rename-buffer'.
+  (defvar bmkp-eww-jumping-p nil
+    "Non-nil only if we are currently jumping to an EWW bookmark.")
+  (make-variable-buffer-local 'bmkp-eww-jumping-p)
+
+  (defun bmkp-eww-title ()
+    "Return the web-page title of the current `eww-mode' buffer."
+    (plist-get eww-data :title))
+
+  (defun bmkp-eww-url ()
+    "Return the URL of the current `eww-mode' buffer."
+    (eww-current-url))
+
+  (defun bmkp-make-eww-record ()
+    "Make a record for an EWW buffer."
+    `(,(bmkp-eww-title)
+      (buffer-name . ,(bmkp-eww-new-buffer-name))
+      ,@(bookmark-make-record-default 'NO-FILE)
+      (location . ,(bmkp-eww-url))
+      (handler . bmkp-jump-eww)))
+
+  (add-hook 'eww-mode-hook (lambda () (set (make-local-variable 'bookmark-make-record-function)
+                                      'bmkp-make-eww-record)))
+
+  (defun bmkp-eww-new-buffer-name ()
+    "Return a new buffer name for the current `eww-mode' buffer.
+The name format is determined by option `bmkp-eww-buffer-renaming'."
+    (concat "*eww*" (and bmkp-eww-buffer-renaming
+                         (concat "-"
+                                 (bmkp-eww-title)
+                                 (let ((url  (bmkp-eww-url)))
+                                   (and (eq 'url bmkp-eww-buffer-renaming)
+                                        (concat " " (if (>= (length url) 20) (substring url -20) url))))))))
+
+  (defun bmkp-jump-eww (bookmark)
+    "Handler function for record returned by `bmkp-make-eww-record'.
+BOOKMARK is a bookmark name or a bookmark record."
+    (require 'eww)
+    (let ((buffer                 (or (and (not bmkp-eww-generate-buffer-flag)
+                                           (get-buffer (bmkp-get-buffer-name bookmark)))
+                                      (generate-new-buffer "*eww*"))) ; Might get renamed later.
+          ;; VAR `bmkp-eww-new-buf-name' is free here.  It is bound in `bmkp-eww-rename-buffer'.
+          (after-render-function  `(lambda ()
+                                     (when (and bmkp-eww-buffer-renaming  bmkp-eww-new-buf-name)
+                                       (kill-buffer)
+                                       (set-buffer bmkp-eww-new-buf-name))
+                                     (bookmark-default-handler
+                                      `("" (buffer . ,(current-buffer))
+                                        . ,(bmkp-bookmark-data-from-record ,(car bookmark))))
+                                     (dolist (var  '(bmkp-eww-jumping-p eww-after-render-hook))
+                                       (kill-local-variable var)))))
+      (setq bmkp-eww-jumping-p  t)
+      (with-current-buffer buffer
+        (eww-mode)
+        (save-window-excursion ; Save window because it calls `pop-to-buffer-same-window'.
+          (eww (bookmark-location bookmark)))
+        (add-hook 'eww-after-render-hook after-render-function 'APPEND 'LOCAL))))
+
+  (defun bmkp-eww-rename-buffer (&rest _ignored)
+    "Rename current buffer according to option `bmkp-eww-buffer-renaming'.
+When jumping to EWW bookmark with nil `bmkp-eww-generate-buffer-flag',
+if the buffer has already been visited, set `bmkp-eww-new-buf-name' so
+that `bmkp-jump-eww' will use the already visited buffer."
+    (when bmkp-eww-buffer-renaming
+      (let ((new-bname  (bmkp-eww-new-buffer-name)))
+        (condition-case nil
+            (rename-buffer new-bname)
+          ;; VAR `bmkp-eww-jumping-p' is free here.  It is set in `bmkp-jump-eww'.
+          (error (if (and bmkp-eww-jumping-p  (not bmkp-eww-generate-buffer-flag))
+                     (setq bmkp-eww-new-buf-name  new-bname) ; For `after-render-function' in `bmkp-jump-eww'.
+                   (rename-buffer (generate-new-buffer-name new-bname))))))))
+
+  ;; The EWW buffer is renamed on each visit, if `bmkp-eww-buffer-renaming' is non-nil.
+  (eval-after-load "eww"
+    '(when (> emacs-major-version 24)   ; Emacs 25+
+       (add-hook   'eww-after-render-hook      'bmkp-eww-rename-buffer)
+       (advice-add 'eww-restore-history :after 'bmkp-eww-rename-buffer)))
+
+
+  ;; Eval this so that even if the library is byte-compiled with Emacs 20,
+  ;; loading it into Emacs 22+ will define variable `bmkp-eww-auto-bookmark-mode'.
+  (eval '(define-minor-mode bmkp-eww-auto-bookmark-mode
+           "Toggle automatically setting a bookmark when you visit a URL with EWW.
+The bookmark name is the title of the web page.
+
+If option `bmkp-eww-auto-type' is `create-or-update' then such a
+bookmark is created for the URL if none exists.  If the option value
+is `update-only' then no new bookmark is created automatically, but an
+existing bookmark is updated.  (Updating a bookmark increments the
+recorded number of visits.)  You can toggle the option using
+`\\[bmkp-toggle-eww-auto-type]'."
+           :init-value nil :global t :group 'bookmark-plus :require 'bookmark+
+           :lighter bmkp-automatic-bookmark-mode-lighter
+           :link `(url-link :tag "Send Bug Report"
+                            ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\
+Bookmark bug: \
+&body=Describe bug here, starting with `emacs -Q'.  \
+Don't forget to mention your Emacs and library versions."))
+           :link '(url-link :tag "Download" "https://www.emacswiki.org/emacs/download/bookmark%2b.el")
+           :link '(url-link :tag "Description" "https://www.emacswiki.org/emacs/BookmarkPlus")
+           :link '(emacs-commentary-link :tag "Commentary" "bookmark+")
+           (cond (bmkp-eww-auto-bookmark-mode
+                  (add-hook   'eww-after-render-hook      'bmkp-set-eww-bookmark-here)
+                  (advice-add 'eww-restore-history :after 'bmkp-set-eww-bookmark-here))
+                 (t
+                  (remove-hook   'eww-after-render-hook   'bmkp-set-eww-bookmark-here)
+                  (advice-remove 'eww-restore-history     'bmkp-set-eww-bookmark-here)))
+           (when (interactive-p)
+             (message "Automatic EWW bookmarking is now %s"
+                      (if bmkp-eww-auto-bookmark-mode
+                          (if (eq bmkp-eww-auto-type 'update-only)
+                              "ON, updating only"
+                            "ON, creating or UPDATING")
+                        "OFF")))))
+
+  (defun bmkp-set-eww-bookmark-here (&optional nomsg)
+    "Set an EWW bookmark for the URL of the current EWW buffer.
+The current buffer is assumed to be in `eww-mode' and visiting a URL."
+    (interactive)
+    (let* ((bname   (bmkp-eww-title))
+           (url     (bmkp-eww-url))
+           (bmk     (bmkp-get-bookmark bname 'NO-ERROR))
+           (visits  (and bmk  (bookmark-prop-get bmk 'visits))))
+      (when bname
+        (cond ((and (not visits)  (eq bmkp-eww-auto-type 'create-or-update))
+               (bookmark-set bname)
+               (unless nomsg (message "Created EWW bookmark `%s'" bname)))
+              (visits
+               (bmkp-record-visit bname 'BATCHP)
+               (bmkp-refresh/rebuild-menu-list bname nil)
+               (bmkp-maybe-save-bookmarks)
+               (unless nomsg (message "Updated EWW bookmark `%s'" bname)))))))
+
+  (defun bmkp-toggle-eww-auto-type (&optional msgp)
+    "Toggle the value of option `bmkp-eww-auto-type'."
+    (interactive "p")
+    (setq bmkp-eww-auto-type  (if (eq bmkp-eww-auto-type 'create-or-update) 'update-only 'create-or-update))
+    (when msgp (message "`bmkp-eww-auto-bookmark-mode' now %s"
+                        (if (eq bmkp-eww-auto-type 'create-or-update)
+                            "CREATES, as well as updates, EWW bookmarks"
+                          "only UPDATES EXISTING EWW bookmarks"))))
+
+
+  ;; You can use this to convert existing EWW bookmarks to Bookmark+ bookmarks.
+  ;;
+  (defun bmkp-convert-eww-bookmarks (eww-file bmk-file &optional msgp)
+    "Add bookmarks from EWW-FILE to BMK-FILE.
+EWW-FILE is a file of \"bookmarks\" created by EWW, which are not
+compatible with Emacs bookmarks.  EWW-FILE is not modified.
+
+BMK-FILE is a Bookmark+ bookmarks file, which is an ordinary Emacs
+bookmarks file (possibly with Bookmark+-specific bookmarks).
+
+If BMK-FILE exists then it is updated to include the converted
+bookmarks.  If it does not exist then it is created."
+    (interactive
+     (let* ((std-default  (bmkp-default-bookmark-file))
+            (default      (if (bmkp-same-file-p bmkp-current-bookmark-file bmkp-last-bookmark-file)
+                              (if (bmkp-same-file-p bmkp-current-bookmark-file std-default)
+                                  bookmark-default-file
+                                std-default)
+                            bmkp-last-bookmark-file)))
+       (list (bmkp-read-bookmark-file-name "EWW bookmark file: "
+                                           nil
+                                           (expand-file-name "eww-bookmarks" user-emacs-directory)
+                                           t)
+             (bmkp-read-bookmark-file-name "Emacs bookmark file to update: "
+                                           (or (file-name-directory default)  "~/")
+                                           (if (bmkp-same-file-p bmkp-current-bookmark-file
+                                                                 bmkp-last-bookmark-file)
+                                               (bmkp-default-bookmark-file)
+                                             bmkp-last-bookmark-file))
+             t)))
+    (when (file-directory-p eww-file) (error "`%s' is a directory, not a file" eww-file))
+    (unless (file-readable-p eww-file) (error "Cannot read bookmark file `%s'" eww-file))
+    (when (file-directory-p bmk-file) (error "`%s' is a directory, not a file" bmk-file))
+    (unless (file-readable-p bmk-file) (bmkp-empty-file bmk-file)) ; Create empty bookmark file.
+    (with-temp-buffer
+      (insert-file-contents eww-file)
+      (let ((bookmark-alist  ())
+            url title created bmk)
+        (dolist (ebmk  (read (current-buffer)))
+          (setq url      (plist-get ebmk :url)
+                title    (plist-get ebmk :title)
+                created  (date-to-time (plist-get ebmk :time))
+                bmk      `(,title
+                           ,@(bookmark-make-record-default 'NO-FILE)
+                           (location . ,url)
+                           (handler . bmkp-jump-eww)))
+          (let ((buf-cell  (assq 'buffer-name bmk))) (setcdr buf-cell "*eww*"))
+          (let ((created-cell  (assq 'created bmk))) (setcdr created-cell created))
+          (push bmk bookmark-alist))
+        (bookmark-write-file bmk-file 'ADD)))
+    (when msgp (message "Wrote Bookmark file `%s'" bmk-file)))
+
+  )
+
+;; W3M support
+(defun bmkp-make-w3m-record ()
+  "Make a special entry for w3m buffers."
+  (require 'w3m)                        ; For `w3m-current-url'.
+  `(,w3m-current-title
+    ,@(bookmark-make-record-default 'NO-FILE)
+    (location . ,w3m-current-url)
+    (handler . bmkp-jump-w3m)))
+
+(add-hook 'w3m-mode-hook (lambda () (set (make-local-variable 'bookmark-make-record-function)
+                                         'bmkp-make-w3m-record)))
+
+(defun bmkp-w3m-set-new-buffer-name ()
+  "Set the w3m buffer name according to the number of W3M buffers already open."
+  (require 'w3m)                        ; For `w3m-list-buffers'.
+  (let ((len  (length (w3m-list-buffers 'nosort))))
+    (if (= len 0)  "*w3m*"  (format "*w3m*<%d>" (1+ len)))))
+
+(defalias 'bmkp-jump-w3m-new-session 'bmkp-jump-w3m-new-buffer)
+(defun bmkp-jump-w3m-new-buffer (bookmark)
+  "Jump to W3M bookmark BOOKMARK in a new buffer (in a new W3M tab)."
+  (require 'w3m)
+  (let ((buf   (bmkp-w3m-set-new-buffer-name)))
+    (w3m-browse-url (bookmark-location bookmark) 'newsession)
+    (while (not (get-buffer buf)) (sit-for 1)) ; Be sure we have the W3M buffer.
+    (with-current-buffer (get-buffer-create buf)
+      (goto-char (point-min))
+      ;; Wait until data arrives in buffer, before setting region.
+      (while (eq (line-beginning-position) (line-end-position)) (sit-for 1)))
+    (bookmark-default-handler `("" (buffer . ,buf) . ,(bmkp-bookmark-data-from-record bookmark)))))
+
+(defalias 'bmkp-jump-w3m-only-one-tab 'bmkp-jump-w3m-only-one-buffer)
+(defun bmkp-jump-w3m-only-one-buffer (bookmark)
+  "Close all W3M sessions and jump to BOOKMARK in a new W3M buffer."
+  (require 'w3m)
+  (w3m-quit 'force)                     ; Be sure we start with an empty W3M buffer.
+  (w3m-browse-url (bookmark-location bookmark))
+  (with-current-buffer (get-buffer-create "*w3m*") (while (eq (point-min) (point-max)) (sit-for 1)))
+  (bookmark-default-handler `("" (buffer . "*w3m*") . ,(bmkp-bookmark-data-from-record bookmark))))
+
+(defalias 'bmkext-jump-w3m 'bmkp-jump-w3m)
+(defun bmkp-jump-w3m (bookmark)
+  "Handler function for record returned by `bmkp-make-w3m-record'.
+BOOKMARK is a bookmark name or a bookmark record.
+Use a new buffer (tab) if `bmkp-w3m-allow-multiple-buffers-flag' is
+non-nil."
+  (require 'w3m)
+  (if bmkp-w3m-allow-multiple-buffers-flag
+      (bmkp-jump-w3m-new-buffer bookmark)
+    (bmkp-jump-w3m-only-one-buffer bookmark)))
+
+
+;; GNUS support for Emacs < 24.  More or less the same as `gnus-summary-bookmark-make-record' in Emacs 24+.
+;; But this:
+;;
+;; * Works for other Emacs versions as well.
+;; * Requires `gnus.el'.
+;; * Adds a `bmkp-non-file-filename' `filename' entry.
+;; * Uses `bmkp-jump-gnus', not `gnus-summary-bookmark-jump' as the handler.
+;;
+(defun bmkp-make-gnus-record ()
+  "Make a bookmark entry for a Gnus summary buffer.
+Current buffer can be the article buffer or the summary buffer."
+  (require 'gnus)
+  (let ((pos  nil)
+        buf)
+    ;; If in article buffer, record point and buffer, then go to summary buffer
+    ;; and record bookmark there.
+    (unless (and (if (fboundp 'derived-mode-p)
+                     (derived-mode-p 'gnus-summary-mode)
+                   (eq major-mode 'gnus-summary-mode))
+                 gnus-article-current)
+      (setq buf                      "art"
+            bookmark-yank-point      (point)
+            bookmark-current-buffer  (current-buffer))
+      (save-restriction (widen) (setq pos  (point))) ; Position in article buffer.
+      (gnus-article-show-summary))
+    (let* ((grp   (car gnus-article-current))
+           (art   (cdr gnus-article-current))
+           (head  (gnus-summary-article-header art))
+           (id    (mail-header-id head)))
+      (unless buf (setq buf  "sum"))
+      `((elt (gnus-summary-article-header) 1) ; Subject.
+        ,@(condition-case
+           nil
+           (bookmark-make-record-default ; POS = nil if started in summary buffer.
+            'NO-FILE 'NO-CONTEXT pos nil 'NO-REGION)
+           (wrong-number-of-arguments (bookmark-make-record-default 'POINT-ONLY)))
+        (location . ,(format "Gnus-%s %s:%d:%s" buf grp art id))
+        (filename . ,bmkp-non-file-filename) (group . ,grp) (article . ,art) (message-id . ,id)
+        (handler . bmkp-jump-gnus)))))  ; Vanilla Emacs 24+ uses `gnus-summary-bookmark-jump'.
+
+
+;; Vanilla Emacs 24+ uses `gnus-summary-bookmark-make-record' for these hooks.
+;; Better to use `bmkp-make-gnus-record' even for Emacs 24+, because `bmkp-jump-gnus' is better than
+;; `gnus-summary-bookmark-jump' (no `sit-for' if article buffer not needed).
+
+;; $$$$$$ (unless (> emacs-major-version 23) ; Emacs 24 has `gnus-summary-bookmark-make-record'.
+(add-hook 'gnus-summary-mode-hook (lambda ()
+                                    (set (make-local-variable 'bookmark-make-record-function)
+                                         'bmkp-make-gnus-record)))
+
+;; $$$$$$ (unless (> emacs-major-version 23) ; Emacs 24 has `gnus-summary-bookmark-make-record'.
+(add-hook 'gnus-article-mode-hook (lambda ()
+                                    (set (make-local-variable 'bookmark-make-record-function)
+                                         'bmkp-make-gnus-record)))
+
+;; More or less the same as `gnus-summary-bookmark-jump' in Emacs 24+.
+;; But this does not `sit-for' unless BUF is "Gnus-art".
+;;
+(defun bmkp-jump-gnus (bookmark)
+  "Handler function for record returned by `bmkp-make-gnus-record'.
+BOOKMARK is a bookmark name or a bookmark record."
+  (let* ((group    (bookmark-prop-get bookmark 'group))
+         (article  (bookmark-prop-get bookmark 'article))
+         (id       (bookmark-prop-get bookmark 'message-id))
+         (loc      (bookmark-prop-get bookmark 'location))
+         (buf      (if loc (car (split-string loc)) (bookmark-prop-get bookmark 'buffer))))
+    (if (< emacs-major-version 22) (gnus-fetch-group group) (gnus-fetch-group group (list article)))
+    (gnus-summary-insert-cached-articles)
+    (gnus-summary-goto-article id nil 'force)
+    ;; Go to article buffer if appropriate.  Wait for it to be ready, so `bookmark-default-handler' has time
+    ;; to set the right position.
+    (when (equal buf "Gnus-art")  (sit-for 1) (other-window 1))
+    (bookmark-default-handler `("" (buffer . ,buf) . ,(bmkp-bookmark-data-from-record bookmark)))))
+
+(defun bmkext-jump-gnus (bookmark)      ; Compatibility code.
+  "`gnus-summary-bookmark-jump' if defined, else `bmkp-jump-gnus'."
+  (if (fboundp 'gnus-summary-bookmark-jump)
+      (gnus-summary-bookmark-jump bookmark) ; Emacs 24
+    (bmkp-jump-gnus bookmark)))
+
+
+;; `man' and `woman' support for Emacs < 24.
+
+(when (> emacs-major-version 20)
+  (defun bmkp-make-woman-record ()
+    "Create bookmark record for `man' page bookmark created by `woman'."
+    `(,@(bookmark-make-record-default 'NO-FILE)
+      (filename . ,woman-last-file-name) (handler . bmkp-jump-woman)))
+
+  (unless (> emacs-major-version 23)
+    (add-hook 'woman-mode-hook (lambda ()
+                                 (set (make-local-variable 'bookmark-make-record-function)
+                                      'bmkp-make-woman-record)))))
+
+(defun bmkp-make-man-record ()
+  "Create bookmark record for `man' page bookmark created by `man'."
+  `(,@(bookmark-make-record-default 'NO-FILE)
+    (filename . ,bmkp-non-file-filename)
+    (man-args . ,Man-arguments) (handler . bmkp-jump-man)))
+
+(unless (> emacs-major-version 23)
+  (add-hook 'Man-mode-hook (lambda () (set (make-local-variable 'bookmark-make-record-function)
+                                           'bmkp-make-man-record))))
+
+(defun bmkext-jump-woman (bookmark)     ; Compatibility code.
+  "`woman-bookmark-jump' if defined, else `bmkp-jump-woman'."
+  (if (fboundp 'woman-bookmark-jump)
+      (woman-bookmark-jump bookmark)    ; Emacs 24
+    (bmkp-jump-woman bookmark)))
+
+(defun bmkp-jump-woman (bookmark)
+  "Handler function for `man' page bookmark created by `woman'.
+BOOKMARK is a bookmark name or a bookmark record."
+  (unless (> emacs-major-version 20)
+    (error "`woman' bookmarks are not supported in Emacs prior to Emacs 21"))
+  (bookmark-default-handler
+   `("" (buffer . ,(save-window-excursion (woman-find-file (bookmark-get-filename bookmark))
+                                          (current-buffer)))
+     . ,(bmkp-bookmark-data-from-record bookmark))))
+
+(defun bmkext-jump-man (bookmark)       ; Compatibility code.
+  "`Man-bookmark-jump' if defined, else `bmkp-jump-man'."
+  (if (fboundp 'Man-bookmark-jump)
+      (Man-bookmark-jump bookmark)      ; Emacs 24
+    (bmkp-jump-man bookmark)))
+
+(defun bmkp-jump-man (bookmark)
+  "Handler function for `man' page bookmark created by `man'.
+BOOKMARK is a bookmark name or a bookmark record."
+  (require 'man)
+  (let* ((man-args           (bookmark-prop-get bookmark 'man-args))
+         ;; `Man-notify-method' binding needs to be in effect during the calls to both
+         ;; `Man-getpage-in-background' and `accept-process-output'.
+         (Man-notify-method  (case bmkp-jump-display-function
+                               ((nil display-buffer)             'quiet)
+                               (bmkp--pop-to-buffer-same-window  'pushy)
+                               ((bmkp-select-buffer-other-window
+                                 switch-to-buffer-other-window
+                                 pop-to-buffer)
+                                'friendly)
+                               (t                                'quiet)))
+         (buf                (Man-getpage-in-background man-args))
+         (proc               (and (bufferp buf) ; Emacs 24+
+                                  (get-buffer-process buf))))
+    (if proc
+        (while (and proc (eq (process-status proc) 'run)) (accept-process-output proc))
+      (while (get-process "man") (sit-for 0.2)))
+    (bookmark-default-handler (bmkp-get-bookmark bookmark))))
+
+(defun bmkp-dired-remember-*-marks (beg end)
+  "Return a list of the files and subdirs marked `*' in Dired."
+  (if (fboundp 'dired--unhide)          ; Emacs 27+ uses invisible text, not `selective-display'.
+      (with-silent-modifications (dired--unhide (point-min) (point-max)))
+    (when selective-display (let ((inhibit-read-only  t)) (subst-char-in-region beg end ?\r ?\n))))
+  (let ((mfiles  ())
+        fil)
+    (save-excursion (goto-char beg)
+                    (while (re-search-forward "^\\*" end t) ; Not `dired-re-mark' - match only `*' marks.
+                      (when (setq fil  (dired-get-filename nil t)) (push fil mfiles))))
+    (nreverse mfiles)))
+
+(defun bmkp-make-dired-record ()
+  "Create and return a Dired bookmark record."
+  (let ((hidden-dirs  (save-excursion (dired-remember-hidden))))
+    (unwind-protect
+         (let ((dir      (expand-file-name (if (consp dired-directory)
+                                               (file-name-directory (car dired-directory))
+                                             dired-directory)))
+               (subdirs  (bmkp-dired-subdirs))
+               (mfiles   (bmkp-dired-remember-*-marks (point-min) (point-max))))
+           `(,dir
+             ,@(bookmark-make-record-default 'NO-FILE)
+             (filename . ,dir) (dired-directory . ,dired-directory)
+             (dired-marked . ,mfiles) (dired-switches . ,dired-actual-switches)
+             (dired-subdirs . ,subdirs) (dired-hidden-dirs . ,hidden-dirs)
+             (handler . bmkp-jump-dired)))
+      (save-excursion                   ; Hide subdirs that were hidden.
+        (dolist (dir  hidden-dirs)  (when (dired-goto-subdir dir) (dired-hide-subdir 1)))))))
+
+;;;###autoload (autoload 'bmkp-dired-subdirs "bookmark+")
+(defun bmkp-dired-subdirs ()
+  "Alist of inserted subdirectories, without their positions (markers).
+This is like `dired-subdir-alist' but without the top-level dir and
+without subdir positions (markers)."
+  (interactive)
+  (let ((subdir-alist      (cdr (reverse dired-subdir-alist))) ; Remove top.
+        (subdirs-wo-posns  ()))
+    (dolist (sub  subdir-alist)  (push (list (car sub)) subdirs-wo-posns))
+    subdirs-wo-posns))
+
+(add-hook 'dired-mode-hook (lambda () (set (make-local-variable 'bookmark-make-record-function)
+                                           'bmkp-make-dired-record)))
+
+(defun bmkp-jump-dired (bookmark)
+  "Jump to Dired bookmark BOOKMARK.
+Handler function for record returned by `bmkp-make-dired-record'.
+BOOKMARK is a bookmark name or a bookmark record."
+  (let ((dir          (bookmark-prop-get bookmark 'dired-directory))
+        (mfiles       (bookmark-prop-get bookmark 'dired-marked))
+        (switches     (bookmark-prop-get bookmark 'dired-switches))
+        (subdirs      (bookmark-prop-get bookmark 'dired-subdirs))
+        (hidden-dirs  (bookmark-prop-get bookmark 'dired-hidden-dirs)))
+    (case bmkp-jump-display-function
+      ((nil bmkp--pop-to-buffer-same-window display-buffer)
+       (dired dir switches))
+      ((bmkp-select-buffer-other-window pop-to-buffer switch-to-buffer-other-window)
+       (dired-other-window dir switches))
+      (t (dired dir switches)))
+    (let ((inhibit-read-only  t))
+      (dired-insert-old-subdirs subdirs)
+      (dired-mark-remembered (mapcar (lexical-let ((dd  dir))
+                                       (lambda (mf) (cons (expand-file-name mf dd) 42)))
+                                     mfiles))
+      (save-excursion (dolist (dir  hidden-dirs) (when (dired-goto-subdir dir) (dired-hide-subdir 1)))))
+    (let ((pos  (bookmark-get-position bookmark))) (when pos (goto-char pos)))))
+
+(defun bmkp-read-bookmark-for-type (type alist &optional other-win pred hist action prompt)
+  "Read name of a bookmark of type TYPE in ALIST, and return the bookmark.
+TYPE is a string used in the prompt: \"Jump to TYPE bookmark: \".
+ALIST is the alist used for completion.  If nil then raise an error to
+ let the user know there are no bookmarks of type TYPE.
+Non-nil OTHER-WIN means append \" in another window\" to the prompt.
+Non-nil PRED is a predicate used for bookmark-name completion.
+Non-nil HIST is a history symbol.  Default is `bookmark-history'.
+Non-nil ACTION is the action mentioned in the prompt; nil: `Jump to '.
+Non-nil PROMPT is an alternative prompt."
+  (unless alist (error "No bookmarks of type %s" type))
+  (bmkp-bookmark-record-from-name
+   (bookmark-completing-read (or prompt  (concat (or action  "Jump to ") type " bookmark"
+                                                 (and other-win  " in another window")))
+                             (bmkp-default-bookmark-name alist)
+                             alist pred hist)
+   'NOERROR nil alist))
+
+;;;###autoload (autoload 'bmkp-jump-to-type "bookmark+")
+(defun bmkp-jump-to-type (bookmark &optional flip-use-region-p) ; `C-x j :'
+  "Jump to a bookmark of a given type.  You are prompted for the type.
+Otherwise, this is the same as `bookmark-jump' - see that, in
+particular, for info about using a prefix argument.
+
+When prompted for the type, you can use completion against the known
+bookmark types (see function `bmkp-types-alist').
+
+Completion is lax, so you can also enter the name of a bookmark
+`handler' or `file-handler' function, without completion.  Bookmarks
+with that entry value are then the jump candidates.
+
+When called from Lisp, BOOKMARK must be a bookmark record, not a
+bookmark name, or else an error is raised."
+  (interactive
+   (let* ((completion-ignore-case                      t)
+          (type-cands                                  (bmkp-types-alist))
+          (icicle-unpropertize-completion-result-flag  t)
+          (type                                        (completing-read "Type of bookmark: " type-cands))
+          (history                                     (assoc-default type type-cands))
+          (alist                                       (if history
+                                                           (funcall
+                                                            (intern (format "bmkp-%s-alist-only" type)))
+                                                         bookmark-alist))
+          (bmk                                         (bmkp-read-bookmark-for-type
+                                                        type alist nil
+                                                        ;; PREDICATE if not a recognized type name.
+                                                        (and (not history)
+                                                             (bmkp-handler-pred (intern type)))
+                                                        history)))
+     (list bmk  (or (equal type "Region")  current-prefix-arg))))
+  (when (stringp bookmark) (error "Not a bookmark record (perhaps a bookmark name): `%s'" bookmark))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-jump-to-type-other-window "bookmark+")
+(defun bmkp-jump-to-type-other-window (bookmark &optional flip-use-region-p) ; `C-x 4 j :'
+  "`bmkp-jump-to-type', but in another window."
+  (interactive
+   (let* ((completion-ignore-case                      t)
+          (type-cands                                  (bmkp-types-alist))
+          (icicle-unpropertize-completion-result-flag  t)
+          (type                                        (completing-read "Type of bookmark: " type-cands))
+          (history                                     (assoc-default type type-cands))
+          (alist                                       (if history
+                                                           (funcall
+                                                            (intern (format "bmkp-%s-alist-only" type)))
+                                                         bookmark-alist))
+          (bmk-name                                    (bmkp-read-bookmark-for-type
+                                                        type alist t
+                                                        ;; PREDICATE if not a recognized type name.
+                                                        (and (not history)
+                                                             (bmkp-handler-pred (intern type)))
+                                                        history)))
+     (list bmk-name (or (equal type "Region")  current-prefix-arg))))
+  (when (stringp bookmark) (error "Not a bookmark record (perhaps a bookmark name): `%s'" bookmark))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window flip-use-region-p))
+
+(defun bmkp-handler-pred (type)
+  "Return a bookmark predicate that tests bookmarks with handler TYPE.
+More precisely, the predicate returns non-nil if TYPE is either the
+bookmark's `handler' or `file-handler' entry value."
+  `(lambda (bmk)
+    (member ',type `(,(bookmark-prop-get bmk 'file-handler) ,(bookmark-get-handler bmk)))))
+
+;;;###autoload (autoload 'bmkp-autonamed-jump "bookmark+")
+(defun bmkp-autonamed-jump (bookmark) ; `C-x j #'
+  "Jump to an autonamed bookmark.
+This is a specialization of `bookmark-jump'."
+  (interactive
+   (let ((alist  (bmkp-autonamed-alist-only)))
+     (list (bmkp-read-bookmark-for-type "autonamed" alist nil nil 'bmkp-autonamed-history))))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-autonamed-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window))
+
+;;;###autoload (autoload 'bmkp-autonamed-jump-other-window "bookmark+")
+(defun bmkp-autonamed-jump-other-window (bookmark) ; `C-x 4 j # #'
+  "`bmkp-autonamed-jump', but in another window."
+  (interactive
+   (let ((alist  (bmkp-autonamed-alist-only)))
+     (list (bmkp-read-bookmark-for-type "autonamed" alist t nil 'bmkp-autonamed-history))))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-autonamed-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window))
+
+;;;###autoload (autoload 'bmkp-autonamed-this-buffer-jump "bookmark+")
+(defun bmkp-autonamed-this-buffer-jump (bookmark) ; `C-x j , #'
+  "Jump to an autonamed bookmark in the current buffer.
+This is a specialization of `bookmark-jump'."
+  (interactive
+   (let ((alist  (bmkp-autonamed-this-buffer-alist-only)))
+     (list (bmkp-read-bookmark-for-type "autonamed" alist nil nil 'bmkp-autonamed-history))))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-autonamed-this-buffer-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window))
+
+;;;###autoload (autoload 'bmkp-autonamed-this-buffer-jump-other-window "bookmark+")
+(defun bmkp-autonamed-this-buffer-jump-other-window (bookmark) ; `C-x 4 j # .'
+  "`bmkp-autonamed-this-buffer-jump', but in another window."
+  (interactive
+   (let ((alist  (bmkp-autonamed-this-buffer-alist-only)))
+     (list (bmkp-read-bookmark-for-type "autonamed" alist t nil 'bmkp-autonamed-history))))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-autonamed-this-buffer-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window))
+
+;;;###autoload (autoload 'bmkp-bookmark-list-jump "bookmark+")
+(defun bmkp-bookmark-list-jump (bookmark &optional flip-use-region-p) ; `C-x j B'
+  "Jump to a bookmark-list bookmark.
+This is a specialization of `bookmark-jump' - see that, in particular
+for info about using a prefix argument."
+  (interactive
+   (let ((alist  (bmkp-bookmark-list-alist-only)))
+     (list (bmkp-read-bookmark-for-type "bookmark-list" alist nil nil 'bmkp-bookmark-list-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-bookmark-list-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-desktop-jump "bookmark+")
+(defun bmkp-desktop-jump (bookmark &optional flip-use-region-p) ; `C-x j K'
+  "Jump to a desktop bookmark.
+If option `bmkp-desktop-jump-save-before-flag' is non-nil, and if the
+current desktop was made current by jumping to a bookmark, then save
+it before jumping to the next desktop.
+
+This command is a specialization of `bookmark-jump' - see that, in
+particular for info about using a prefix argument."
+  (interactive
+   (let ((alist  (bmkp-desktop-alist-only)))
+     (list (bmkp-read-bookmark-for-type "desktop" alist nil nil 'bmkp-desktop-history)
+           current-prefix-arg)))
+  (when bmkp-desktop-jump-save-before-flag (bmkp-desktop-save-as-last))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-desktop-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window flip-use-region-p)
+  (setq bmkp-desktop-current-file  (bookmark-prop-get bookmark 'desktop-file)))
+
+;;;###autoload (autoload 'bmkp-dired-jump "bookmark+")
+(defun bmkp-dired-jump (bookmark &optional flip-use-region-p) ; `C-x j d', (`J' in Dired)
+  "Jump to a Dired bookmark.
+This is a specialization of `bookmark-jump' - see that, in particular
+for info about using a prefix argument."
+  (interactive
+   (let ((alist  (bmkp-dired-alist-only)))
+     (list (bmkp-read-bookmark-for-type "Dired" alist nil nil 'bmkp-dired-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-dired-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-dired-jump-other-window "bookmark+")
+(defun bmkp-dired-jump-other-window (bookmark &optional flip-use-region-p) ; `C-x 4 j d'
+  "`bmkp-dired-jump', but in another window."
+  (interactive
+   (let ((alist  (bmkp-dired-alist-only)))
+     (list (bmkp-read-bookmark-for-type "Dired" alist t nil 'bmkp-dired-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-dired-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-dired-this-dir-jump "bookmark+")
+(defun bmkp-dired-this-dir-jump (bookmark &optional flip-use-region-p) ; `C-x j . d', (`C-j' in Dired)
+  "Jump to a Dired bookmark for the `default-directory'.
+This is a specialization of `bookmark-jump' - see that, in particular
+for info about using a prefix argument."
+  (interactive
+   (let ((alist  (bmkp-dired-this-dir-alist-only)))
+     (list (bmkp-read-bookmark-for-type "Dired-for-this-dir " alist nil nil 'bmkp-dired-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-dired-this-dir-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-dired-this-dir-jump-other-window "bookmark+")
+(defun bmkp-dired-this-dir-jump-other-window (bookmark &optional flip-use-region-p) ; `C-x 4 j C-d'
+  "`bmkp-dired-this-dir-jump', but in another window."
+  (interactive
+   (let ((alist  (bmkp-dired-this-dir-alist-only)))
+     (list (bmkp-read-bookmark-for-type "Dired-for-this-dir" alist t nil 'bmkp-dired-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-dired-this-dir-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window flip-use-region-p))
+
+(when (fboundp 'bmkp-eww-alist-only)    ; Emacs 25+
+
+  ;; ;;;###autoload (autoload 'bmkp-eww-jump "bookmark+")
+  (defun bmkp-eww-jump (bookmark &optional flip-use-region-p) ; `C-x j e'
+    "Jump to an EWW bookmark.
+This is a specialization of `bookmark-jump' - see that, in particular
+for info about using a prefix argument."
+    (interactive
+     (let ((alist  (bmkp-eww-alist-only)))
+       (list (bmkp-read-bookmark-for-type "EWW" alist nil nil 'bmkp-eww-history)
+             current-prefix-arg)))
+    (when (stringp bookmark)
+      (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-eww-alist-only))))
+    (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+  ;; ;;;###autoload (autoload 'bmkp-eww-jump-other-window "bookmark+")
+  (defun bmkp-eww-jump-other-window (bookmark &optional flip-use-region-p) ; `C-x 4 j e'
+    "`bmkp-eww-jump', but in another window."
+    (interactive
+     (let ((alist  (bmkp-eww-alist-only)))
+       (list (bmkp-read-bookmark-for-type "EWW" alist t nil 'bmkp-eww-history)
+             current-prefix-arg)))
+    (when (stringp bookmark)
+      (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-eww-alist-only))))
+    (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window flip-use-region-p))
+
+  )
+
+;;;###autoload (autoload 'bmkp-file-jump "bookmark+")
+(defun bmkp-file-jump (bookmark &optional flip-use-region-p) ; `C-x j f'
+  "Jump to a file or directory bookmark.
+This is a specialization of `bookmark-jump' - see that, in particular
+for info about using a prefix argument."
+  (interactive
+   (let ((alist  (bmkp-file-alist-only)))
+     (list (bmkp-read-bookmark-for-type "file" alist nil nil 'bmkp-file-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-file-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-file-jump-other-window "bookmark+")
+(defun bmkp-file-jump-other-window (bookmark &optional flip-use-region-p) ; `C-x 4 j f'
+  "`bmkp-file-jump', but in another window."
+  (interactive
+   (let ((alist  (bmkp-file-alist-only)))
+     (list (bmkp-read-bookmark-for-type "file" alist t nil 'bmkp-file-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-file-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-file-this-dir-jump "bookmark+")
+(defun bmkp-file-this-dir-jump (bookmark &optional flip-use-region-p) ; `C-x j . f'
+  "Jump to a bookmark for a file or subdir in the `default-directory'.
+This is a specialization of `bookmark-jump' - see that, in particular
+for info about using a prefix argument."
+  (interactive
+   (let ((alist  (bmkp-file-this-dir-alist-only)))
+     (list (bmkp-read-bookmark-for-type "file-in-this-dir" alist nil nil 'bmkp-file-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-file-this-dir-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-file-this-dir-jump-other-window "bookmark+")
+(defun bmkp-file-this-dir-jump-other-window (bookmark &optional flip-use-region-p) ; `C-x 4 j . f'
+  "`bmkp-file-this-dir-jump', but in another window."
+  (interactive
+   (let ((alist  (bmkp-file-this-dir-alist-only)))
+     (list (bmkp-read-bookmark-for-type "file-in-this-dir" alist t nil 'bmkp-file-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-file-this-dir-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-gnus-jump "bookmark+")
+(defun bmkp-gnus-jump (bookmark &optional flip-use-region-p) ; `C-x j g', (`j' in Gnus summary mode)
+  "Jump to a Gnus bookmark.
+This is a specialization of `bookmark-jump' - see that, in particular
+for info about using a prefix argument."
+  (interactive
+   (let ((alist  (bmkp-gnus-alist-only)))
+     (list (bmkp-read-bookmark-for-type "Gnus" alist nil nil 'bmkp-gnus-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-gnus-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-gnus-jump-other-window "bookmark+")
+(defun bmkp-gnus-jump-other-window (bookmark &optional flip-use-region-p) ; `C-x 4 j g'
+  "`bmkp-gnus-jump', but in another window."
+  (interactive
+   (let ((alist  (bmkp-gnus-alist-only)))
+     (list (bmkp-read-bookmark-for-type "Gnus" alist t nil 'bmkp-gnus-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-gnus-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-image-jump "bookmark+")
+(defun bmkp-image-jump (bookmark &optional flip-use-region-p) ; `C-x j M-i'
+  "Jump to an image-file bookmark.
+This is a specialization of `bookmark-jump' - see that, in particular
+for info about using a prefix argument."
+  (interactive
+   (let ((alist  (bmkp-image-alist-only)))
+     (list (bmkp-read-bookmark-for-type "image" alist nil nil 'bmkp-image-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-image-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-image-jump-other-window "bookmark+")
+(defun bmkp-image-jump-other-window (bookmark &optional flip-use-region-p) ; `C-x j M-i'
+  "`bmkp-image-jump', but in another window."
+  (interactive
+   (let ((alist  (bmkp-image-alist-only)))
+     (list (bmkp-read-bookmark-for-type "image" alist t nil 'bmkp-image-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-image-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-info-jump "bookmark+")
+(defun bmkp-info-jump (bookmark &optional flip-use-region-p) ; `C-x j i', (`j' in Info)
+  "Jump to an Info bookmark.
+This is a specialization of `bookmark-jump' - see that, in particular
+for info about using a prefix argument."
+  (interactive
+   (let ((alist  (bmkp-info-alist-only)))
+     (list (bmkp-read-bookmark-for-type "Info" alist nil nil 'bmkp-info-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-info-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-info-jump-other-window "bookmark+")
+(defun bmkp-info-jump-other-window (bookmark &optional flip-use-region-p) ; `C-x 4 j i'
+  "`bmkp-info-jump', but in another window."
+  (interactive
+   (let ((alist  (bmkp-info-alist-only)))
+     (list (bmkp-read-bookmark-for-type "Info" alist t nil 'bmkp-info-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-info-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-local-file-jump "bookmark+")
+(defun bmkp-local-file-jump (bookmark &optional flip-use-region-p) ; `C-x j l'
+  "Jump to a local file or directory bookmark.
+This is a specialization of `bookmark-jump' - see that, in particular
+for info about using a prefix argument."
+  (interactive
+   (let ((alist  (bmkp-local-file-alist-only)))
+     (list (bmkp-read-bookmark-for-type "local file" alist nil nil 'bmkp-local-file-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-local-file-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-local-file-jump-other-window "bookmark+")
+(defun bmkp-local-file-jump-other-window (bookmark &optional flip-use-region-p) ; `C-x 4 j l'
+  "`bmkp-local-file-jump', but in another window."
+  (interactive
+   (let ((alist  (bmkp-local-file-alist-only)))
+     (list (bmkp-read-bookmark-for-type "local file" alist t nil 'bmkp-local-file-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-local-file-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-local-non-dir-file-jump "bookmark+")
+(defun bmkp-local-non-dir-file-jump (bookmark &optional flip-use-region-p) ; Not bound
+  "Jump to a local nondirectory file bookmark.
+This is a specialization of `bookmark-jump' - see that, in particular
+for info about using a prefix argument."
+  (interactive
+   (let ((alist  (bmkp-local-non-dir-file-alist-only)))
+     (list (bmkp-read-bookmark-for-type "local non-dir file" alist nil nil 'bmkp-local-file-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-local-non-dir-file-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-local-non-dir-file-jump-other-window "bookmark+")
+(defun bmkp-local-non-dir-file-jump-other-window (bookmark &optional flip-use-region-p) ; Not bound
+  "`bmkp-local-non-dir-file-jump', but in another window."
+  (interactive
+   (let ((alist  (bmkp-local-non-dir-file-alist-only)))
+     (list (bmkp-read-bookmark-for-type "local non-dir file" alist t nil 'bmkp-local-file-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-local-non-dir-file-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-man-jump "bookmark+")
+(defun bmkp-man-jump (bookmark &optional flip-use-region-p) ; `C-x j m', (`j' in Man)
+  "Jump to a `man'-page bookmark.
+This is a specialization of `bookmark-jump' - see that, in particular
+for info about using a prefix argument."
+  (interactive
+   (let ((alist  (bmkp-man-alist-only)))
+     (list (bmkp-read-bookmark-for-type "`man'" alist nil nil 'bmkp-man-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-man-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-man-jump-other-window "bookmark+")
+(defun bmkp-man-jump-other-window (bookmark &optional flip-use-region-p) ; `C-x 4 j m'
+  "`bmkp-man-jump', but in another window."
+  (interactive
+   (let ((alist  (bmkp-man-alist-only)))
+     (list (bmkp-read-bookmark-for-type "`man'" alist t nil 'bmkp-man-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-man-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-non-dir-file-jump "bookmark+")
+(defun bmkp-non-dir-file-jump (bookmark &optional flip-use-region-p) ; Not bound
+  "Jump to a nondirectory file bookmark.
+This is a specialization of `bookmark-jump' - see that, in particular
+for info about using a prefix argument."
+  (interactive
+   (let ((alist  (bmkp-non-dir-file-alist-only)))
+     (list (bmkp-read-bookmark-for-type "non-dir file" alist nil nil 'bmkp-file-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-non-dir-file-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-non-dir-file-jump-other-window "bookmark+")
+(defun bmkp-non-dir-file-jump-other-window (bookmark &optional flip-use-region-p) ; Not bound
+  "`bmkp-non-dir-file-jump', but in another window."
+  (interactive
+   (let ((alist  (bmkp-non-dir-file-alist-only)))
+     (list (bmkp-read-bookmark-for-type "non-dir file" alist t nil 'bmkp-file-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-non-dir-file-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-non-file-jump "bookmark+")
+(defun bmkp-non-file-jump (bookmark &optional flip-use-region-p) ; `C-x j b', (`j' in Buffer Menu)
+  "Jump to a non-file (buffer) bookmark.
+This is a specialization of `bookmark-jump' - see that, in particular
+for info about using a prefix argument."
+  (interactive
+   (let ((alist  (bmkp-non-file-alist-only)))
+     (list (bmkp-read-bookmark-for-type "non-file (buffer)" alist nil nil 'bmkp-non-file-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-non-file-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-non-file-jump-other-window "bookmark+")
+(defun bmkp-non-file-jump-other-window (bookmark &optional flip-use-region-p) ; `C-x 4 j b'
+  "`bmkp-non-file-jump', but in another window."
+  (interactive
+   (let ((alist  (bmkp-non-file-alist-only)))
+     (list (bmkp-read-bookmark-for-type "non-file (buffer)" alist t nil 'bmkp-non-file-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-non-file-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-region-jump "bookmark+")
+(defun bmkp-region-jump (bookmark) ; `C-x j r'
+  "Jump to a region bookmark.  Select the region.
+This is a specialization of `bookmark-jump', but without a prefix arg.
+BOOKMARK is a bookmark name or a bookmark record."
+  (interactive (list (bmkp-read-bookmark-for-type "region" (bmkp-region-alist-only) nil nil
+                                                  'bmkp-region-history)))
+  (let ((bmkp-use-region  t)) (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window)))
+
+;;;###autoload (autoload 'bmkp-region-jump-other-window "bookmark+")
+(defun bmkp-region-jump-other-window (bookmark) ; `C-x 4 j r'
+  "`bmkp-region-jump', but in another window."
+  (interactive (list (bmkp-read-bookmark-for-type "region" (bmkp-region-alist-only) t nil
+                                                  'bmkp-region-history)))
+  (let ((bmkp-use-region  t)) (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window)))
+
+;; This command accepts no argument.  It calls another command interactively, which reads the bookmark name.
+;;
+;;;###autoload (autoload 'bmkp-region-jump-narrow-indirect-other-window "bookmark+")
+(defun bmkp-region-jump-narrow-indirect-other-window ()
+  "Jump to a region bookmark and narrow to it in a cloned indirect buffer.
+You are prompted for the region bookmark.
+
+The region is selected as usual, in the bookmarked file/buffer.  A
+separate window is opened on the region text, for the cloned indirect
+buffer.
+
+You need library `narrow-indirect.el' to use this command."
+  (interactive)
+  (unless (require 'narrow-indirect nil t)
+    (error "You need library `narrow-indirect.el' for this command"))
+  (let ((bmkp-handle-region-function  'bmkp-handle-region+narrow-indirect))
+    (call-interactively
+     (if (and (boundp 'icicle-mode)  icicle-mode) ; Icicles
+         #'icicle-bookmark-region-other-window
+       #'bmkp-region-jump-other-window))))
+
+(defun bmkp-handle-region+narrow-indirect (bookmark)
+  "`bmkp-handle-region-default', then narrow to region in cloned buffer."
+  (let ((bmkp-handle-region-function  'bmkp-handle-region-default))
+    (bookmark-handle-bookmark bookmark))
+  (if (get major-mode 'no-clone-indirect) ; e.g., `Info-mode'
+      (message "Cannot indirectly clone a buffer in `%s' mode" major-mode)
+    (ni-narrow-to-region-indirect-other-window (region-beginning) (region-end) (point))))
+
+;;;###autoload (autoload 'bmkp-remote-file-jump "bookmark+")
+(defun bmkp-remote-file-jump (bookmark &optional flip-use-region-p) ; `C-x j n'
+  "Jump to a remote file or directory bookmark.
+This is a specialization of `bookmark-jump' - see that, in particular
+for info about using a prefix argument."
+  (interactive
+   (let ((alist  (bmkp-remote-file-alist-only)))
+     (list (bmkp-read-bookmark-for-type "remote file" alist nil nil 'bmkp-remote-file-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-remote-file-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-remote-file-jump-other-window "bookmark+")
+(defun bmkp-remote-file-jump-other-window (bookmark &optional flip-use-region-p) ; `C-x 4 j n'
+  "`bmkp-remote-file-jump', but in another window."
+  (interactive
+   (let ((alist  (bmkp-remote-file-alist-only)))
+     (list (bmkp-read-bookmark-for-type "remote file" alist t nil 'bmkp-remote-file-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-remote-file-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-remote-non-dir-file-jump "bookmark+")
+(defun bmkp-remote-non-dir-file-jump (bookmark &optional flip-use-region-p) ; Not bound
+  "Jump to a remote nondirectory file bookmark.
+This is a specialization of `bookmark-jump' - see that, in particular
+for info about using a prefix argument."
+  (interactive
+   (let ((alist  (bmkp-remote-non-dir-file-alist-only)))
+     (list (bmkp-read-bookmark-for-type "remote non-dir file" alist nil nil 'bmkp-remote-file-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-remote-non-dir-file-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-remote-non-dir-file-jump-other-window "bookmark+")
+(defun bmkp-remote-non-dir-file-jump-other-window (bookmark &optional flip-use-region-p) ; Not bound
+  "`bmkp-remote-non-dir-file-jump', but in another window."
+  (interactive
+   (let ((alist  (bmkp-remote-non-dir-file-alist-only)))
+     (list (bmkp-read-bookmark-for-type "remote non-dir file" alist t nil 'bmkp-remote-file-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-remote-non-dir-file-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-specific-buffers-jump "bookmark+")
+(defun bmkp-specific-buffers-jump (buffers bookmark &optional flip-use-region-p) ; `C-x j = b'
+  "Jump to a bookmark for a buffer in list BUFFERS.
+Interactively, read buffer names and bookmark name, with completion.
+
+This is a specialization of `bookmark-jump' - see that, in particular
+for info about using a prefix argument."
+  (interactive
+   (let* ((buffs  (bmkp-read-buffers))
+          (alist  (bmkp-specific-buffers-alist-only buffs)))
+     (list buffs (bmkp-read-bookmark-for-type "specific-buffers" alist nil nil 'specific-buffers-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-specific-buffers-alist-only buffers))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-specific-buffers-jump-other-window "bookmark+")
+(defun bmkp-specific-buffers-jump-other-window (buffers bookmark
+                                                        &optional flip-use-region-p) ; `C-x 4 j = b'
+  "`bmkp-specific-buffers-jump', but in another window."
+  (interactive
+   (let* ((buffs  (bmkp-read-buffers))
+          (alist  (bmkp-specific-buffers-alist-only buffs)))
+     (list buffs (bmkp-read-bookmark-for-type "specific-buffers" alist t nil 'specific-buffers-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-specific-buffers-alist-only buffers))))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-specific-files-jump "bookmark+")
+(defun bmkp-specific-files-jump (files bookmark &optional flip-use-region-p) ; `C-x j = f'
+  "Jump to a bookmark for a file in list FILES.
+Interactively, read file names and bookmark name, with completion.
+
+This is a specialization of `bookmark-jump' - see that, in particular
+for info about using a prefix argument."
+  (interactive
+   (let* ((fils   (bmkp-read-files))
+          (alist  (bmkp-specific-files-alist-only fils)))
+     (list fils
+           (bmkp-read-bookmark-for-type "specific-files" alist nil nil 'specific-files-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-specific-files-alist-only files))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-specific-files-jump-other-window "bookmark+")
+(defun bmkp-specific-files-jump-other-window (files bookmark
+                                                    &optional flip-use-region-p) ; `C-x 4 j = f'
+  "`bmkp-specific-files-jump', but in another window."
+  (interactive
+   (let* ((fils   (bmkp-read-files))
+          (alist  (bmkp-specific-files-alist-only fils)))
+     (list fils
+           (bmkp-read-bookmark-for-type "specific-files" alist t nil 'specific-files-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-specific-files-alist-only files))))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-temporary-jump "bookmark+")
+(defun bmkp-temporary-jump (bookmark) ; `C-x j x'
+  "Jump to a temporary bookmark.
+This is a specialization of `bookmark-jump', but without a prefix arg."
+  (interactive (list (bmkp-read-bookmark-for-type "temporary" (bmkp-temporary-alist-only) nil nil
+                                                  'bmkp-temporary-history)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-temporary-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window))
+
+;;;###autoload (autoload 'bmkp-temporary-jump-other-window "bookmark+")
+(defun bmkp-temporary-jump-other-window (bookmark) ; `C-x 4 j x'
+  "`bmkp-temporary-jump', but in another window."
+  (interactive (list (bmkp-read-bookmark-for-type "temporary" (bmkp-temporary-alist-only) t nil
+                                                  'bmkp-temporary-history)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-temporary-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window))
+
+;;;###autoload (autoload 'bmkp-this-buffer-jump "bookmark+")
+(defun bmkp-this-buffer-jump (bookmark &optional flip-use-region-p) ; `C-x j , ,'
+  "Jump to a bookmark for the current buffer.
+This is a specialization of `bookmark-jump' - see that, in particular
+for info about using a prefix argument."
+  (interactive
+   (let ((alist  (bmkp-this-buffer-alist-only)))
+     (unless alist  (error "No bookmarks for this buffer"))
+     (list (bookmark-completing-read "Jump to bookmark for this buffer"
+                                     (bmkp-default-bookmark-name alist) alist)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-this-buffer-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-this-buffer-jump-other-window "bookmark+")
+(defun bmkp-this-buffer-jump-other-window (bookmark &optional flip-use-region-p) ; `C-x 4 j , ,'
+  "`bmkp-this-buffer-jump', but in another window."
+  (interactive
+   (let ((alist  (bmkp-this-buffer-alist-only)))
+     (unless alist  (error "No bookmarks for this buffer"))
+     (list (bookmark-completing-read "Jump to bookmark for this buffer in another window"
+                                     (bmkp-default-bookmark-name alist) alist)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-this-buffer-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window flip-use-region-p))
+
+;;; ;;;###autoload
+;;; (defun bmkp-this-file-jump (bookmark-name &optional flip-use-region-p)
+;;;   "Jump to a bookmark for the current file (absolute file name).
+;;; This is a specialization of `bookmark-jump' - see that, in particular
+;;; for info about using a prefix argument."
+;;;   (interactive
+;;;    (progn (unless (or (buffer-file-name)  (and (eq major-mode 'dired-mode)
+;;;                                                (if (consp dired-directory)
+;;;                                                    (car dired-directory)
+;;;                                                  dired-directory)))
+;;;             (error "This buffer is not associated with a file"))
+;;;           (let ((alist  (bmkp-this-file-alist-only)))
+;;;             (unless alist  (error "No bookmarks for this file"))
+;;;             (list (bookmark-completing-read "Jump to bookmark for this file"
+;;;                                             (bmkp-default-bookmark-name alist) alist)
+;;;                   current-prefix-arg))))
+;;;   (bmkp-jump-1 bookmark-name 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+;;; ;;;###autoload
+;;; (defun bmkp-this-file-jump-other-window (bookmark-name &optional flip-use-region-p)
+;;;   "`bmkp-this-file-jump', but in another window."
+;;;   (interactive
+;;;    (progn (unless (or (buffer-file-name)  (and (eq major-mode 'dired-mode)
+;;;                                                (if (consp dired-directory)
+;;;                                                    (car dired-directory)
+;;;                                                  dired-directory)))
+;;;             (error "This buffer is not associated with a file"))
+;;;           (let ((alist  (bmkp-this-file-alist-only)))
+;;;             (unless alist  (error "No bookmarks for this file"))
+;;;             (list (bookmark-completing-read "Jump to bookmark for this file in another window"
+;;;                                             (bmkp-default-bookmark-name alist) alist)
+;;;                   current-prefix-arg))))
+;;;   (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-variable-list-jump "bookmark+")
+(defun bmkp-variable-list-jump (bookmark) ; `C-x j v'
+  "Jump to a variable-list bookmark.
+This is a specialization of `bookmark-jump'."
+  (interactive
+   (let ((alist  (bmkp-variable-list-alist-only)))
+     (list (bmkp-read-bookmark-for-type "variable-list" alist nil nil 'bmkp-variable-list-history))))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-variable-list-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window))
+
+;;;###autoload (autoload 'bmkp-url-jump "bookmark+")
+(defun bmkp-url-jump (bookmark &optional flip-use-region-p) ; `C-x j u'
+  "Jump to a URL bookmark.
+It can be an EWW bookmark, a W3M bookmark, or a browse-URL bookmark.
+This is a specialization of `bookmark-jump' - see that, in particular
+for info about using a prefix argument."
+  (interactive
+   (let ((alist  (bmkp-url-alist-only)))
+     (list (bmkp-read-bookmark-for-type "URL" alist nil nil 'bmkp-url-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-url-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-url-jump-other-window "bookmark+")
+(defun bmkp-url-jump-other-window (bookmark &optional flip-use-region-p) ; `C-x 4 j u'
+  "`bmkp-url-jump', but in another window."
+  (interactive
+   (let ((alist  (bmkp-url-alist-only)))
+     (list (bmkp-read-bookmark-for-type "URL" alist t nil 'bmkp-url-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-url-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-w32-browser-jump "bookmark+")
+(defun bmkp-w32-browser-jump (bookmark) ; Not bound
+  "Jump to a bookmark whose handler applies `w32-browser' to its file.
+This is a specialization of `bookmark-jump'."
+  (interactive
+   (list (bmkp-read-bookmark-for-type "w32-browser" bookmark-alist nil
+                                      ;; Use a predicate, since `w32-browser' is a handler, not a type name.
+                                      (bmkp-handler-pred 'w32-browser)
+                                      'bmkp-w32-browser-history)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR)))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window))
+
+;;;###autoload (autoload 'bmkp-w3m-jump "bookmark+")
+(defun bmkp-w3m-jump (bookmark &optional flip-use-region-p) ; `C-x j w', (`j' in W3M)
+  "Jump to a W3M bookmark.
+This is a specialization of `bookmark-jump' - see that, in particular
+for info about using a prefix argument."
+  (interactive
+   (let ((alist  (bmkp-w3m-alist-only)))
+     (list (bmkp-read-bookmark-for-type "W3M" alist nil nil 'bmkp-w3m-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-w3m-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-w3m-jump-other-window "bookmark+")
+(defun bmkp-w3m-jump-other-window (bookmark &optional flip-use-region-p) ; `C-x 4 j w'
+  "`bmkp-w3m-jump', but in another window."
+  (interactive
+   (let ((alist  (bmkp-w3m-alist-only)))
+     (list (bmkp-read-bookmark-for-type "W3M" alist t nil 'bmkp-w3m-history)
+           current-prefix-arg)))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-w3m-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-all-tags-jump "bookmark+")
+(defun bmkp-all-tags-jump (tags bookmark) ; `C-x j t *'
+  "Jump to a BOOKMARK that has all of the TAGS.
+Hit `RET' to enter each tag, then hit `RET' again after the last tag.
+You can use completion to enter the bookmark name and each tag.
+If you specify no tags, then every bookmark that has some tags is a
+candidate.
+
+By default, the tag choices for completion are NOT refreshed, to save
+time.  Use a prefix argument if you want to refresh them."
+  (interactive
+   (let* ((tgs    (bmkp-read-tags-completing nil nil current-prefix-arg))
+          (alist  (bmkp-all-tags-alist-only tgs)))
+     (unless alist (error "No bookmarks have all of the specified tags"))
+     (list tgs (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump bookmark))
+
+;;;###autoload (autoload 'bmkp-all-tags-jump-other-window "bookmark+")
+(defun bmkp-all-tags-jump-other-window (tags bookmark) ; `C-x 4 j t *'
+  "`bmkp-all-tags-jump', but in another window."
+  (interactive
+   (let* ((tgs    (bmkp-read-tags-completing nil nil current-prefix-arg))
+          (alist  (bmkp-all-tags-alist-only tgs)))
+     (unless alist (error "No bookmarks have all of the specified tags"))
+     (list tgs (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump-other-window bookmark))
+
+;;;###autoload (autoload 'bmkp-all-tags-regexp-jump "bookmark+")
+(defun bmkp-all-tags-regexp-jump (regexp bookmark) ; `C-x j t % *'
+  "Jump to a BOOKMARK that has each tag matching REGEXP.
+You are prompted for the REGEXP.
+Then you are prompted for the BOOKMARK (with completion)."
+  (interactive
+   (let* ((rgx    (bmkp-read-regexp "Regexp for all tags: "))
+          (alist  (bmkp-all-tags-regexp-alist-only rgx)))
+     (unless alist (error "No bookmarks have tags that match `%s'" rgx))
+     (list rgx (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump bookmark))
+
+;;;###autoload (autoload 'bmkp-all-tags-regexp-jump-other-window "bookmark+")
+(defun bmkp-all-tags-regexp-jump-other-window (regexp bookmark) ; `C-x 4 j t % *'
+  "`bmkp-all-tags-regexp-jump', but in another window."
+  (interactive
+   (let* ((rgx    (bmkp-read-regexp "Regexp for all tags: "))
+          (alist  (bmkp-all-tags-regexp-alist-only rgx)))
+     (unless alist (error "No bookmarks have tags that match `%s'" rgx))
+     (list rgx (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump-other-window bookmark))
+
+;;;###autoload (autoload 'bmkp-some-tags-jump "bookmark+")
+(defun bmkp-some-tags-jump (tags bookmark) ; `C-x j t +'
+  "Jump to a BOOKMARK that has at least one of the TAGS.
+Hit `RET' to enter each tag, then hit `RET' again after the last tag.
+You can use completion to enter the bookmark name and each tag.
+
+By default, the tag choices for completion are NOT refreshed, to save
+time.  Use a prefix argument if you want to refresh them."
+  (interactive
+   (let* ((tgs    (bmkp-read-tags-completing nil nil current-prefix-arg))
+          (alist  (bmkp-some-tags-alist-only tgs)))
+     (unless tgs (error "You did not specify any tags"))
+     (unless alist (error "No bookmarks have any of the specified tags"))
+     (list tgs (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump bookmark))
+
+;;;###autoload (autoload 'bmkp-some-tags-jump-other-window "bookmark+")
+(defun bmkp-some-tags-jump-other-window (tags bookmark) ; `C-x 4 j t +'
+  "`bmkp-some-tags-jump', but in another window."
+  (interactive
+   (let* ((tgs    (bmkp-read-tags-completing nil nil current-prefix-arg))
+          (alist  (bmkp-some-tags-alist-only tgs)))
+     (unless tgs (error "You did not specify any tags"))
+     (unless alist (error "No bookmarks have any of the specified tags"))
+     (list tgs (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump-other-window bookmark))
+
+;;;###autoload (autoload 'bmkp-some-tags-regexp-jump "bookmark+")
+(defun bmkp-some-tags-regexp-jump (regexp bookmark) ; `C-x j t % +'
+  "Jump to a BOOKMARK that has a tag matching REGEXP.
+You are prompted for the REGEXP.
+Then you are prompted for the BOOKMARK (with completion)."
+  (interactive
+   (let* ((rgx    (bmkp-read-regexp "Regexp for tags: "))
+          (alist  (bmkp-some-tags-regexp-alist-only rgx)))
+     (unless alist (error "No bookmarks have tags that match `%s'" rgx))
+     (list rgx (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump bookmark))
+
+;;;###autoload (autoload 'bmkp-some-tags-regexp-jump-other-window "bookmark+")
+(defun bmkp-some-tags-regexp-jump-other-window (regexp bookmark) ; `C-x 4 j t % +'
+  "`bmkp-some-tags-regexp-jump', but in another window."
+  (interactive
+   (let* ((rgx    (bmkp-read-regexp "Regexp for tags: "))
+          (alist  (bmkp-some-tags-regexp-alist-only rgx)))
+     (unless alist (error "No bookmarks have tags that match `%s'" rgx))
+     (list rgx (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump-other-window bookmark))
+
+;;;###autoload (autoload 'bmkp-file-all-tags-jump "bookmark+")
+(defun bmkp-file-all-tags-jump (tags bookmark) ; `C-x j t f *'
+  "Jump to a file or directory BOOKMARK that has all of the TAGS.
+Hit `RET' to enter each tag, then hit `RET' again after the last tag.
+You can use completion to enter the bookmark name and each tag.
+If you specify no tags, then every bookmark that has some tags is a
+candidate.
+
+By default, the tag choices for completion are NOT refreshed, to save
+time.  Use a prefix argument if you want to refresh them."
+  (interactive
+   (let* ((tgs    (bmkp-read-tags-completing nil nil current-prefix-arg))
+          (alist  (bmkp-file-all-tags-alist-only tgs)))
+     (unless alist (error "No file or dir bookmarks have all of the specified tags"))
+     (list tgs (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump bookmark))
+
+;;;###autoload (autoload 'bmkp-file-all-tags-jump-other-window "bookmark+")
+(defun bmkp-file-all-tags-jump-other-window (tags bookmark) ; `C-x 4 j t f *'
+  "`bmkp-file-all-tags-jump', but in another window."
+  (interactive
+   (let* ((tgs    (bmkp-read-tags-completing nil nil current-prefix-arg))
+          (alist  (bmkp-file-all-tags-alist-only tgs)))
+     (unless alist (error "No file or dir bookmarks have all of the specified tags"))
+     (list tgs (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump-other-window bookmark))
+
+;;;###autoload (autoload 'bmkp-file-all-tags-regexp-jump "bookmark+")
+(defun bmkp-file-all-tags-regexp-jump (regexp bookmark) ; `C-x j t f % *'
+  "Jump to a file or directory BOOKMARK that has each tag matching REGEXP.
+You are prompted for the REGEXP.
+Then you are prompted for the BOOKMARK (with completion)."
+  (interactive
+   (let* ((rgx    (bmkp-read-regexp "Regexp for tags: "))
+          (alist  (bmkp-file-all-tags-regexp-alist-only rgx)))
+     (unless alist (error "No file or dir bookmarks have tags that match `%s'" rgx))
+     (list rgx (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump bookmark))
+
+;;;###autoload (autoload 'bmkp-file-all-tags-regexp-jump-other-window "bookmark+")
+(defun bmkp-file-all-tags-regexp-jump-other-window (regexp bookmark) ; `C-x 4 j t f % *'
+  "`bmkp-file-all-tags-regexp-jump', but in another window."
+  (interactive
+   (let* ((rgx    (bmkp-read-regexp "Regexp for tags: "))
+          (alist  (bmkp-file-all-tags-regexp-alist-only rgx)))
+     (unless alist (error "No file or dir bookmarks have tags that match `%s'" rgx))
+     (list rgx (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump-other-window bookmark))
+
+;;;###autoload (autoload 'bmkp-file-some-tags-jump "bookmark+")
+(defun bmkp-file-some-tags-jump (tags bookmark) ; `C-x j t f +'
+  "Jump to a file or directory BOOKMARK that has at least one of the TAGS.
+Hit `RET' to enter each tag, then hit `RET' again after the last tag.
+You can use completion to enter the bookmark name and each tag.
+
+By default, the tag choices for completion are NOT refreshed, to save
+time.  Use a prefix argument if you want to refresh them."
+  (interactive
+   (let* ((tgs    (bmkp-read-tags-completing nil nil current-prefix-arg))
+          (alist  (bmkp-file-some-tags-alist-only tgs)))
+     (unless tgs (error "You did not specify any tags"))
+     (unless alist (error "No file or dir bookmarks have any of the specified tags"))
+     (list tgs (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump bookmark))
+
+;;;###autoload (autoload 'bmkp-file-some-tags-jump-other-window "bookmark+")
+(defun bmkp-file-some-tags-jump-other-window (tags bookmark) ; `C-x 4 j t f +'
+  "`bmkp-file-some-tags-jump', but in another window."
+  (interactive
+   (let* ((tgs    (bmkp-read-tags-completing nil nil current-prefix-arg))
+          (alist  (bmkp-file-some-tags-alist-only tgs)))
+     (unless tgs (error "You did not specify any tags"))
+     (unless alist (error "No file or dir bookmarks have any of the specified tags"))
+     (list tgs (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump-other-window bookmark))
+
+;;;###autoload (autoload 'bmkp-file-some-tags-regexp-jump "bookmark+")
+(defun bmkp-file-some-tags-regexp-jump (regexp bookmark) ; `C-x j t f % +'
+  "Jump to a file or directory BOOKMARK that has a tag matching REGEXP.
+You are prompted for the REGEXP.
+Then you are prompted for the BOOKMARK (with completion)."
+  (interactive
+   (let* ((rgx    (bmkp-read-regexp "Regexp for tags: "))
+          (alist  (bmkp-file-some-tags-regexp-alist-only rgx)))
+     (unless alist (error "No file or dir bookmarks have tags that match `%s'" rgx))
+     (list rgx (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump bookmark))
+
+;;;###autoload (autoload 'bmkp-file-some-tags-regexp-jump-other-window "bookmark+")
+(defun bmkp-file-some-tags-regexp-jump-other-window (regexp bookmark) ; `C-x 4 j t f % +'
+  "`bmkp-file-some-tags-regexp-jump', but in another window."
+  (interactive
+   (let* ((rgx    (bmkp-read-regexp "Regexp for tags: "))
+          (alist  (bmkp-file-some-tags-regexp-alist-only rgx)))
+     (unless alist (error "No file or dir bookmarks have tags that match `%s'" rgx))
+     (list rgx (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump-other-window bookmark))
+
+;;;###autoload (autoload 'bmkp-file-this-dir-all-tags-jump "bookmark+")
+(defun bmkp-file-this-dir-all-tags-jump (tags bookmark) ; `C-x j t . *'
+  "Jump to a file BOOKMARK in this dir that has all of the TAGS.
+Hit `RET' to enter each tag, then hit `RET' again after the last tag.
+You can use completion to enter the bookmark name and each tag.
+If you specify no tags, then every bookmark that has some tags is a
+candidate.
+
+By default, the tag choices for completion are NOT refreshed, to save
+time.  Use a prefix argument if you want to refresh them."
+  (interactive
+   (let* ((tgs    (bmkp-read-tags-completing nil nil current-prefix-arg))
+          (alist  (bmkp-file-this-dir-all-tags-alist-only tgs)))
+     (unless alist (error "No file or dir bookmarks have all of the specified tags"))
+     (list tgs (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump bookmark))
+
+;;;###autoload (autoload 'bmkp-file-this-dir-all-tags-jump-other-window "bookmark+")
+(defun bmkp-file-this-dir-all-tags-jump-other-window (tags bookmark) ; `C-x 4 j t . *'
+  "`bmkp-file-this-dir-all-tags-jump', but in another window."
+  (interactive
+   (let* ((tgs    (bmkp-read-tags-completing nil nil current-prefix-arg))
+          (alist  (bmkp-file-this-dir-all-tags-alist-only tgs)))
+     (unless alist (error "No file or dir bookmarks have all of the specified tags"))
+     (list tgs (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump-other-window bookmark))
+
+;;;###autoload (autoload 'bmkp-file-this-dir-all-tags-regexp-jump "bookmark+")
+(defun bmkp-file-this-dir-all-tags-regexp-jump (regexp bookmark) ; `C-x j t . % *'
+  "Jump to a file BOOKMARK in this dir that has each tag matching REGEXP.
+You are prompted for the REGEXP.
+Then you are prompted for the BOOKMARK (with completion)."
+  (interactive
+   (let* ((rgx    (bmkp-read-regexp "Regexp for tags: "))
+          (alist  (bmkp-file-this-dir-all-tags-regexp-alist-only rgx)))
+     (unless alist (error "No file or dir bookmarks have tags that match `%s'" rgx))
+     (list rgx (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump bookmark))
+
+;;;###autoload (autoload 'bmkp-file-this-dir-all-tags-regexp-jump-other-window "bookmark+")
+(defun bmkp-file-this-dir-all-tags-regexp-jump-other-window (regexp bookmark) ; `C-x 4 j t . % *'
+  "`bmkp-file-this-dir-all-tags-regexp-jump', but in another window."
+  (interactive
+   (let* ((rgx    (bmkp-read-regexp "Regexp for tags: "))
+          (alist  (bmkp-file-this-dir-all-tags-regexp-alist-only rgx)))
+     (unless alist (error "No file or dir bookmarks have tags that match `%s'" rgx))
+     (list rgx (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump-other-window bookmark))
+
+;;;###autoload (autoload 'bmkp-file-this-dir-some-tags-jump "bookmark+")
+(defun bmkp-file-this-dir-some-tags-jump (tags bookmark) ; `C-x j t . +'
+  "Jump to a file BOOKMARK in this dir that has at least one of the TAGS.
+Hit `RET' to enter each tag, then hit `RET' again after the last tag.
+You can use completion to enter the bookmark name and each tag.
+
+By default, the tag choices for completion are NOT refreshed, to save
+time.  Use a prefix argument if you want to refresh them."
+  (interactive
+   (let* ((tgs    (bmkp-read-tags-completing nil nil current-prefix-arg))
+          (alist  (bmkp-file-this-dir-some-tags-alist-only tgs)))
+     (unless tgs (error "You did not specify any tags"))
+     (unless alist (error "No file or dir bookmarks have any of the specified tags"))
+     (list tgs (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump bookmark))
+
+;;;###autoload (autoload 'bmkp-file-this-dir-some-tags-jump-other-window "bookmark+")
+(defun bmkp-file-this-dir-some-tags-jump-other-window (tags bookmark) ; `C-x 4 j t . +'
+  "`bmkp-file-this-dir-some-tags-jump', but in another window."
+  (interactive
+   (let* ((tgs    (bmkp-read-tags-completing nil nil current-prefix-arg))
+          (alist  (bmkp-file-this-dir-some-tags-alist-only tgs)))
+     (unless tgs (error "You did not specify any tags"))
+     (unless alist (error "No file or dir bookmarks have any of the specified tags"))
+     (list tgs (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump-other-window bookmark))
+
+;;;###autoload (autoload 'bmkp-file-this-dir-some-tags-regexp-jump "bookmark+")
+(defun bmkp-file-this-dir-some-tags-regexp-jump (regexp bookmark) ; `C-x j t . % +'
+  "Jump to a file BOOKMARK in this dir that has a tag matching REGEXP.
+You are prompted for the REGEXP.
+Then you are prompted for the BOOKMARK (with completion)."
+  (interactive
+   (let* ((rgx    (bmkp-read-regexp "Regexp for tags: "))
+          (alist  (bmkp-file-this-dir-some-tags-regexp-alist-only rgx)))
+     (unless alist (error "No file or dir bookmarks have tags that match `%s'" rgx))
+     (list rgx (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump bookmark))
+
+;;;###autoload (autoload 'bmkp-file-this-dir-some-tags-regexp-jump-other-window "bookmark+")
+(defun bmkp-file-this-dir-some-tags-regexp-jump-other-window (regexp bookmark) ; `C-x 4 j t . % +'
+  "`bmkp-file-this-dir-some-tags-regexp-jump', but in another window."
+  (interactive
+   (let* ((rgx    (bmkp-read-regexp "Regexp for tags: "))
+          (alist  (bmkp-file-this-dir-some-tags-regexp-alist-only rgx)))
+     (unless alist (error "No file or dir bookmarks have tags that match `%s'" rgx))
+     (list rgx (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump-other-window bookmark))
+
+;;;###autoload (autoload 'bmkp-autofile-jump "bookmark+")
+(defun bmkp-autofile-jump (bookmark)    ; `C-x j a'
+  "Jump to an autofile bookmark.
+This is a specialization of `bookmark-jump'."
+  (interactive
+   (let ((alist  (bmkp-autofile-alist-only)))
+     (list (bmkp-read-bookmark-for-type "autofile" alist nil nil 'bmkp-autofile-history))))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-autofile-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp--pop-to-buffer-same-window))
+
+;;;###autoload (autoload 'bmkp-autofile-jump-other-window "bookmark+")
+(defun bmkp-autofile-jump-other-window (bookmark) ; `C-x 4 j a'
+  "`bmkp-autofile-jump' but in another window."
+  (interactive
+   (let ((alist  (bmkp-autofile-alist-only)))
+     (list (bmkp-read-bookmark-for-type "autofile" alist t nil 'bmkp-autofile-history))))
+  (when (stringp bookmark)
+    (setq bookmark  (bmkp-get-bookmark-in-alist bookmark 'NOERROR (bmkp-autofile-alist-only))))
+  (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window))
+
+;;;###autoload (autoload 'bmkp-autofile-all-tags-jump "bookmark+")
+(defun bmkp-autofile-all-tags-jump (tags bookmark) ; `C-x j t a *'
+  "Jump to an autofile BOOKMARK in this dir that has all of the TAGS.
+Hit `RET' to enter each tag, then hit `RET' again after the last tag.
+You can use completion to enter the bookmark name and each tag.
+If you specify no tags, then every bookmark that has some tags is a
+candidate.
+
+By default, the tag choices for completion are NOT refreshed, to save
+time.  Use a prefix argument if you want to refresh them."
+  (interactive
+   (let* ((tgs    (bmkp-read-tags-completing nil nil current-prefix-arg))
+          (alist  (bmkp-autofile-all-tags-alist-only tgs)))
+     (unless alist (error "No file or dir bookmarks have all of the specified tags"))
+     (list tgs (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump bookmark))
+
+;;;###autoload (autoload 'bmkp-autofile-all-tags-jump-other-window "bookmark+")
+(defun bmkp-autofile-all-tags-jump-other-window (tags bookmark) ; `C-x 4 j t a *'
+  "`bmkp-autofile-all-tags-jump', but in another window."
+  (interactive
+   (let* ((tgs    (bmkp-read-tags-completing nil nil current-prefix-arg))
+          (alist  (bmkp-autofile-all-tags-alist-only tgs)))
+     (unless alist (error "No file or dir bookmarks have all of the specified tags"))
+     (list tgs (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump-other-window bookmark))
+
+;;;###autoload (autoload 'bmkp-autofile-all-tags-regexp-jump "bookmark+")
+(defun bmkp-autofile-all-tags-regexp-jump (regexp bookmark) ; `C-x j t a % *'
+  "Jump to an autofile BOOKMARK in this dir that has each tag matching REGEXP.
+You are prompted for the REGEXP.
+Then you are prompted for the BOOKMARK (with completion)."
+  (interactive
+   (let* ((rgx    (bmkp-read-regexp "Regexp for tags: "))
+          (alist  (bmkp-autofile-all-tags-regexp-alist-only rgx)))
+     (unless alist (error "No file or dir bookmarks have tags that match `%s'" rgx))
+     (list rgx (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump bookmark))
+
+;;;###autoload (autoload 'bmkp-autofile-all-tags-regexp-jump-other-window "bookmark+")
+(defun bmkp-autofile-all-tags-regexp-jump-other-window (regexp bookmark) ; `C-x 4 j t a % *'
+  "`bmkp-autofile-all-tags-regexp-jump', but in another window."
+  (interactive
+   (let* ((rgx    (bmkp-read-regexp "Regexp for tags: "))
+          (alist  (bmkp-autofile-all-tags-regexp-alist-only rgx)))
+     (unless alist (error "No file or dir bookmarks have tags that match `%s'" rgx))
+     (list rgx (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump-other-window bookmark))
+
+;;;###autoload (autoload 'bmkp-autofile-some-tags-jump "bookmark+")
+(defun bmkp-autofile-some-tags-jump (tags bookmark) ; `C-x j t a +'
+  "Jump to an autofile BOOKMARK in this dir that has at least one of the TAGS.
+Hit `RET' to enter each tag, then hit `RET' again after the last tag.
+You can use completion to enter the bookmark name and each tag.
+
+By default, the tag choices for completion are NOT refreshed, to save
+time.  Use a prefix argument if you want to refresh them."
+  (interactive
+   (let* ((tgs    (bmkp-read-tags-completing nil nil current-prefix-arg))
+          (alist  (bmkp-autofile-some-tags-alist-only tgs)))
+     (unless tgs (error "You did not specify any tags"))
+     (unless alist (error "No file or dir bookmarks have any of the specified tags"))
+     (list tgs (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump bookmark))
+
+;;;###autoload (autoload 'bmkp-autofile-some-tags-jump-other-window "bookmark+")
+(defun bmkp-autofile-some-tags-jump-other-window (tags bookmark) ; `C-x 4 j t a +'
+  "`bmkp-autofile-some-tags-jump', but in another window."
+  (interactive
+   (let* ((tgs    (bmkp-read-tags-completing nil nil current-prefix-arg))
+          (alist  (bmkp-autofile-some-tags-alist-only tgs)))
+     (unless tgs (error "You did not specify any tags"))
+     (unless alist (error "No file or dir bookmarks have any of the specified tags"))
+     (list tgs (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump-other-window bookmark))
+
+;;;###autoload (autoload 'bmkp-autofile-some-tags-regexp-jump "bookmark+")
+(defun bmkp-autofile-some-tags-regexp-jump (regexp bookmark) ; `C-x j t a % +'
+  "Jump to an autofile BOOKMARK in this dir that has a tag matching REGEXP.
+You are prompted for the REGEXP.
+Then you are prompted for the BOOKMARK (with completion)."
+  (interactive
+   (let* ((rgx    (bmkp-read-regexp "Regexp for tags: "))
+          (alist  (bmkp-autofile-some-tags-regexp-alist-only rgx)))
+     (unless alist (error "No file or dir bookmarks have tags that match `%s'" rgx))
+     (list rgx (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump bookmark))
+
+;;;###autoload (autoload 'bmkp-autofile-some-tags-regexp-jump-other-window "bookmark+")
+(defun bmkp-autofile-some-tags-regexp-jump-other-window (regexp bookmark) ; `C-x 4 j t a % +'
+  "`bmkp-autofile-some-tags-regexp-jump', but in another window."
+  (interactive
+   (let* ((rgx    (bmkp-read-regexp "Regexp for tags: "))
+          (alist  (bmkp-autofile-some-tags-regexp-alist-only rgx)))
+     (unless alist (error "No file or dir bookmarks have tags that match `%s'" rgx))
+     (list rgx (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist))))
+  (bookmark-jump-other-window bookmark))
+
+(defun bmkp-find-file (&optional file create-autofile-p must-exist-p msg-p) ; `C-x j C-f'
+  "Visit a file or directory, respecting any associated autofile handlers.
+You are prompted for the file or directory name, FILE.
+
+If FILE matches an entry in `bmkp-default-handlers-for-file-types'
+then use the associated default handler to access the file.
+Otherwise, just use `find-file'.
+
+With a prefix arg, create an autofile bookmark if FILE does not
+already have one.
+
+Non-interactively:
+* Non-nil MUST-EXIST-P means raise an error if FILE has no autofile
+  bookmark.
+* Non-nil MSG-P means display a status message."
+  (interactive "i\nP\ni\np")
+  (let* ((use-file-dialog                             nil)
+         (icicle-unpropertize-completion-result-flag  t) ; For `read-file-name'.
+         (fil                                         (or file  (read-file-name "Find file: " nil nil t)))
+         (dir-to-use                                  (if (file-name-absolute-p fil)
+                                                          (file-name-directory fil)
+                                                        default-directory))
+         (bmk                                         (bmkp-get-autofile-bookmark fil)))
+    (if bmk
+        (bookmark-jump bmk)
+      (when must-exist-p (error "File `%s' is not an autofile (no bookmark)" fil))
+      (when create-autofile-p           ; Create a new bookmark.
+        (bmkp-file-target-set (expand-file-name fil dir-to-use) t nil 'NO-OVERWRITE msg-p)
+        (when msg-p (message "Autofile bookmark set for `%s'" fil)))
+      (let ((default-handler  (condition-case nil (bmkp-default-handler-for-file fil) (error nil))))
+        (if default-handler (funcall default-handler fil) (find-file fil 'WILDCARDS))))))
+
+(defun bmkp-find-file-other-window (&optional file create-autofile-p must-exist-p msg-p) ; `C-x 4 j C-f'
+  "`bmkp-find-file', but in another window."
+  (interactive "i\nP\ni\np")
+  (let* ((use-file-dialog                             nil)
+         (icicle-unpropertize-completion-result-flag  t) ; For `read-file-name'.
+         (fil                                         (or file  (read-file-name "Find file: " nil nil t)))
+         (dir-to-use                                  (if (file-name-absolute-p fil)
+                                                          (file-name-directory fil)
+                                                        default-directory))
+         (bmk                                         (bmkp-get-autofile-bookmark fil dir-to-use)))
+    (if bmk
+        (bookmark-jump-other-window bmk)
+      (when must-exist-p (error "File `%s' is not an autofile (no bookmark)" fil))
+      (when create-autofile-p           ; Create a new bookmark.
+        (bmkp-file-target-set (expand-file-name fil dir-to-use) t nil 'NO-OVERWRITE msg-p)
+        (when msg-p (message "Autofile bookmark created for `%s'" fil)))
+      (let ((default-handler  (condition-case nil (bmkp-default-handler-for-file fil) (error nil))))
+        (if default-handler (funcall default-handler fil) (find-file-other-window fil 'WILDCARDS))))))
+
+
+;;; We could allow these even for Emacs 20 for Icicles users,
+;;; but the predicate would have no effect when not in Icicle mode.  So don't bother with Emacs 20.
+
+(when (> emacs-major-version 21)        ; Needs `read-file-name' with a PREDICATE arg.
+  (defun bmkp-find-file-all-tags (tags &optional file) ; `C-x j t C-f *'
+    "Visit a file or directory that has all of the TAGS.
+You are prompted first for the tags.  Hit `RET' to enter each tag,
+then hit `RET' again after the last tag.  You can use completion to
+enter each tag.  This completion is lax: you are not limited to
+existing tags.
+
+You are then prompted for the file name.  This is read using
+`read-file-name', so you can browse up and down the file hierarchy.
+The completion candidates are file names, not bookmark names.
+However, only files that are bookmarked as autofiles are candidates.
+
+If you specify no tags, then every file that has some tags is a
+candidate.
+
+By default, the tag choices for completion are NOT refreshed, to save
+time.  Use a prefix argument if you want to refresh them."
+    (interactive (list (bmkp-read-tags-completing nil nil current-prefix-arg)))
+    (lexical-let* ((tgs              tags)
+                   (use-file-dialog  nil)
+                   (pred
+                    (lambda (ff)
+                      (lexical-let* ((bmk   (bmkp-get-autofile-bookmark ff))
+                                     (btgs  (and bmk  (bmkp-get-tags bmk))))
+                        (and btgs  (bmkp-every (lambda (tag) (bmkp-has-tag-p bmk tag))  tgs)))))
+                   (icicle-unpropertize-completion-result-flag  t) ; For `read-file-name'.
+                   (icicle-must-pass-after-match-predicate      pred)
+                   (fil                                         (or (and file  (funcall pred file)  file)
+                                                                    (read-file-name
+                                                                     "Find file: " nil nil t nil
+                                                                     (and (or (not (boundp 'icicle-mode))
+                                                                              (not icicle-mode))
+                                                                          pred))))
+                   (bmk                                         (bmkp-get-autofile-bookmark fil)))
+      (when bmk  (bookmark-jump bmk)))))
+
+(when (> emacs-major-version 21)        ; Needs `read-file-name' with a PREDICATE arg.
+  (defun bmkp-find-file-all-tags-other-window (tags &optional file) ; `C-x 4 j t C-f *'
+    "`bmkp-find-file-all-tags', but in another window."
+    (interactive (list (bmkp-read-tags-completing nil nil current-prefix-arg)))
+    (lexical-let* ((tgs              tags)
+                   (use-file-dialog  nil)
+                   (pred
+                    (lambda (ff)
+                      (lexical-let* ((bk    (bmkp-get-autofile-bookmark ff))
+                                     (btgs  (and bk  (bmkp-get-tags bk))))
+                        (and btgs  (bmkp-every (lambda (tag) (bmkp-has-tag-p bk tag))  tgs)))))
+                   (icicle-unpropertize-completion-result-flag  t) ; For `read-file-name'.
+                   (icicle-must-pass-after-match-predicate      pred)
+                   (fil                                         (or (and file  (funcall pred file)  file)
+                                                                    (read-file-name
+                                                                     "Find file: " nil nil t nil
+                                                                     (and (or (not (boundp 'icicle-mode))
+                                                                              (not icicle-mode))
+                                                                          pred))))
+                   (bmk                                         (bmkp-get-autofile-bookmark fil)))
+      (bookmark-jump-other-window bmk))))
+
+(when (> emacs-major-version 21)        ; Needs `read-file-name' with a PREDICATE arg.
+  (defun bmkp-find-file-all-tags-regexp (regexp &optional file) ; `C-x j t C-f % *'
+    "Visit a file or directory that has each tag matching REGEXP.
+You are prompted for the REGEXP."
+    (interactive (list (bmkp-read-regexp "Regexp for tags: ")))
+    (lexical-let* ((rg               regexp)
+                   (use-file-dialog  nil)
+                   (pred
+                    (lambda (ff)
+                      (let* ((bk    (bmkp-get-autofile-bookmark ff))
+                             (btgs  (and bk  (bmkp-get-tags bk))))
+                        (and btgs  (bmkp-every (lambda (tag) (bmkp-string-match-p rg (bmkp-tag-name tag)))
+                                               btgs)))))
+                   (icicle-unpropertize-completion-result-flag  t) ; For `read-file-name'.
+                   (icicle-must-pass-after-match-predicate      pred)
+                   (fil                                         (or (and file  (funcall pred file)  file)
+                                                                    (read-file-name
+                                                                     "Find file: " nil nil t nil
+                                                                     (and (or (not (boundp 'icicle-mode))
+                                                                              (not icicle-mode))
+                                                                          pred))))
+                   (bmk                                         (bmkp-get-autofile-bookmark fil)))
+      (bookmark-jump bmk))))
+
+;;;###autoload (autoload 'bmkp-find-file-all-tags-regexp-other-window "bookmark+")
+(when (> emacs-major-version 21)        ; Needs `read-file-name' with a PREDICATE arg.
+  (defun bmkp-find-file-all-tags-regexp-other-window (regexp &optional file) ; `C-x 4 j t C-f % *'
+    "`bmkp-find-file-all-tags-regexp', but in another window."
+    (interactive (list (bmkp-read-regexp "Regexp for tags: ")))
+    (lexical-let* ((rg               regexp)
+                   (use-file-dialog  nil)
+                   (pred
+                    (lambda (ff)
+                      (let* ((bk    (bmkp-get-autofile-bookmark ff))
+                             (btgs  (and bk  (bmkp-get-tags bk))))
+                        (and btgs  (bmkp-every (lambda (tag) (bmkp-string-match-p rg (bmkp-tag-name tag)))
+                                               btgs)))))
+                   (icicle-unpropertize-completion-result-flag  t) ; For `read-file-name'.
+                   (icicle-must-pass-after-match-predicate      pred)
+                   (fil                                         (or (and file  (funcall pred file)  file)
+                                                                    (read-file-name
+                                                                     "Find file: " nil nil t nil
+                                                                     (and (or (not (boundp 'icicle-mode))
+                                                                              (not icicle-mode))
+                                                                          pred))))
+                   (bmk                                         (bmkp-get-autofile-bookmark fil)))
+      (bookmark-jump-other-window bmk))))
+
+;;;###autoload (autoload 'bmkp-find-file-some-tags "bookmark+")
+(when (> emacs-major-version 21)        ; Needs `read-file-name' with a PREDICATE arg.
+  (defun bmkp-find-file-some-tags (tags &optional file) ; `C-x j t C-f +'
+    "Visit a file or directory that has at least one of the TAGS.
+You are prompted first for the tags.  Hit `RET' to enter each tag,
+then hit `RET' again after the last tag.  You can use completion to
+enter each tag.  This completion is lax: you are not limited to
+existing tags.
+
+You are then prompted for the file name.  This is read using
+`read-file-name', so you can browse up and down the file hierarchy.
+The completion candidates are file names, not bookmark names.
+However, only files that are bookmarked as autofiles are candidates.
+
+By default, the tag choices for completion are NOT refreshed, to save
+time.  Use a prefix argument if you want to refresh them."
+    (interactive (list (bmkp-read-tags-completing nil nil current-prefix-arg)))
+    (lexical-let* ((tgs              tags)
+                   (use-file-dialog  nil)
+                   (pred
+                    (lambda (ff)
+                      (lexical-let* ((bk    (bmkp-get-autofile-bookmark ff))
+                                     (btgs  (and bk  (bmkp-get-tags bk))))
+                        (and btgs  (bmkp-some (lambda (tag) (bmkp-has-tag-p bk tag))  tgs)))))
+                   (icicle-unpropertize-completion-result-flag  t) ; For `read-file-name'.
+                   (icicle-must-pass-after-match-predicate      pred)
+                   (fil                                         (or (and file  (funcall pred file)  file)
+                                                                    (read-file-name
+                                                                     "Find file: " nil nil t nil
+                                                                     (and (or (not (boundp 'icicle-mode))
+                                                                              (not icicle-mode))
+                                                                          pred))))
+                   (bmk                                         (bmkp-get-autofile-bookmark fil)))
+      (bookmark-jump bmk))))
+
+;;;###autoload (autoload 'bmkp-find-file-some-tags-other-window "bookmark+")
+(when (> emacs-major-version 21)        ; Needs `read-file-name' with a PREDICATE arg.
+  (defun bmkp-find-file-some-tags-other-window (tags &optional file) ; `C-x 4 j t C-f +'
+    "`bmkp-find-file-some-tags', but in another window."
+    (interactive (list (bmkp-read-tags-completing nil nil current-prefix-arg)))
+    (lexical-let* ((tgs              tags)
+                   (use-file-dialog  nil)
+                   (pred
+                    (lambda (ff)
+                      (lexical-let* ((bk    (bmkp-get-autofile-bookmark ff))
+                                     (btgs  (and bk  (bmkp-get-tags bk))))
+                        (and btgs  (bmkp-some (lambda (tag) (bmkp-has-tag-p bk tag))  tgs)))))
+                   (icicle-unpropertize-completion-result-flag  t) ; For `read-file-name'.
+                   (icicle-must-pass-after-match-predicate      pred)
+                   (fil                                         (or (and file  (funcall pred file)  file)
+                                                                    (read-file-name
+                                                                     "Find file: " nil nil t nil
+                                                                     (and (or (not (boundp 'icicle-mode))
+                                                                              (not icicle-mode))
+                                                                          pred))))
+                   (bmk                                         (bmkp-get-autofile-bookmark fil)))
+      (bookmark-jump-other-window bmk))))
+
+;;;###autoload (autoload 'bmkp-find-file-some-tags-regexp "bookmark+")
+(when (> emacs-major-version 21)        ; Needs `read-file-name' with a PREDICATE arg.
+  (defun bmkp-find-file-some-tags-regexp (regexp &optional file) ; `C-x j t C-f % +'
+    "Visit a file or directory that has a tag matching REGEXP.
+You are prompted for the REGEXP."
+    (interactive (list (bmkp-read-regexp "Regexp for tags: ")))
+    (lexical-let* ((rg               regexp)
+                   (use-file-dialog  nil)
+                   (pred
+                    (lambda (ff)
+                      (let* ((bk    (bmkp-get-autofile-bookmark ff))
+                             (btgs  (and bk  (bmkp-get-tags bk))))
+                        (and btgs  (bmkp-some (lambda (tag) (bmkp-string-match-p rg (bmkp-tag-name tag)))
+                                              btgs)))))
+                   (icicle-unpropertize-completion-result-flag  t) ; For `read-file-name'.
+                   (icicle-must-pass-after-match-predicate      pred)
+                   (fil                                         (or (and file  (funcall pred file)  file)
+                                                                    (read-file-name
+                                                                     "Find file: " nil nil t nil
+                                                                     (and (or (not (boundp 'icicle-mode))
+                                                                              (not icicle-mode))
+                                                                          pred))))
+                   (bmk                                         (bmkp-get-autofile-bookmark fil)))
+      (bookmark-jump bmk))))
+
+;;;###autoload (autoload 'bmkp-find-file-some-tags-regexp-other-window "bookmark+")
+(when (> emacs-major-version 21)        ; Needs `read-file-name' with a PREDICATE arg.
+  (defun bmkp-find-file-some-tags-regexp-other-window (regexp &optional file) ; `C-x 4 j t C-f % +'
+    "`bmkp-find-file-some-tags-regexp', but in another window."
+    (interactive (list (bmkp-read-regexp "Regexp for tags: ")))
+    (lexical-let* ((rg               regexp)
+                   (use-file-dialog  nil)
+                   (pred
+                    (lambda (ff)
+                      (let* ((bk    (bmkp-get-autofile-bookmark ff))
+                             (btgs  (and bk  (bmkp-get-tags bk))))
+                        (and btgs  (bmkp-some (lambda (tag) (bmkp-string-match-p rg (bmkp-tag-name tag)))
+                                              btgs)))))
+                   (icicle-unpropertize-completion-result-flag  t) ; For `read-file-name'.
+                   (icicle-must-pass-after-match-predicate      pred)
+                   (fil                                         (or (and file  (funcall pred file)  file)
+                                                                    (read-file-name
+                                                                     "Find file: " nil nil t nil
+                                                                     (and (or (not (boundp 'icicle-mode))
+                                                                              (not icicle-mode))
+                                                                          pred))))
+                   (bmk                                         (bmkp-get-autofile-bookmark fil)))
+      (bookmark-jump-other-window bmk))))
+
+;;;###autoload (autoload 'bmkp-jump-in-navlist "bookmark+")
+(defun bmkp-jump-in-navlist (bookmark-name &optional flip-use-region-p) ; `C-x j N'
+  "Jump to a bookmark, choosing from those in the navigation list."
+  (interactive
+   (progn (unless bmkp-nav-alist
+            (bookmark-maybe-load-default-file)
+            (setq bmkp-nav-alist  bookmark-alist)
+            (unless bmkp-nav-alist (error "No bookmarks"))
+            (setq bmkp-current-nav-bookmark  (car bmkp-nav-alist))
+            (message "Bookmark navigation list is now the global bookmark list") (sit-for 2))
+          (let ((bookmark-alist  bmkp-nav-alist))
+            (list (bookmark-completing-read "Jump to bookmark" (bmkp-default-bookmark-name))
+                  current-prefix-arg))))
+  (bmkp-jump-1 bookmark-name 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-jump-in-navlist-other-window "bookmark+")
+(defun bmkp-jump-in-navlist-other-window (bookmark-name &optional flip-use-region-p) ; `C-x 4 j N'
+  "Same as `bmkp-jump-in-navlist', but use another window."
+  (interactive
+   (progn (unless bmkp-nav-alist
+            (bookmark-maybe-load-default-file)
+            (setq bmkp-nav-alist  bookmark-alist)
+            (unless bmkp-nav-alist (error "No bookmarks"))
+            (setq bmkp-current-nav-bookmark  (car bmkp-nav-alist))
+            (message "Bookmark navigation list is now the global bookmark list") (sit-for 2))
+          (let ((bookmark-alist  bmkp-nav-alist))
+            (list (bookmark-completing-read "Jump to bookmark (in another window)"
+                                            (bmkp-default-bookmark-name))
+                  current-prefix-arg))))
+  (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-cycle "bookmark+")
+(defun bmkp-cycle (increment &optional other-window startoverp)
+  "Cycle through bookmarks in the navlist by INCREMENT (default: 1).
+Positive INCREMENT cycles forward.  Negative INCREMENT cycles backward.
+Interactively, the prefix arg determines INCREMENT:
+ Plain `C-u': 1
+ otherwise: the numeric prefix arg value
+
+Plain `C-u' also means start over at first bookmark.
+
+You can set the navigation list using commands
+ `bmkp-choose-navlist-from-bookmark-list' and
+ `bmkp-choose-navlist-of-type'.
+
+You can cycle among bookmarks in the current buffer using
+ `bmkp-cycle-this-buffer' and
+ `bmkp-cycle-this-buffer-other-window.'
+
+In Lisp code:
+ Non-nil OTHER-WINDOW means jump to the bookmark in another window.
+ Non-nil STARTOVERP means reset `bmkp-current-nav-bookmark' to the
+ first bookmark in the navlist."
+  (interactive (let ((startovr  (consp current-prefix-arg)))
+                 (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) nil startovr)))
+  (unless bmkp-nav-alist
+    (bookmark-maybe-load-default-file)
+    (when (and bookmark-alist  (y-or-n-p "No navigation list.  Use whole bookmark list? "))
+      (setq bmkp-nav-alist  bookmark-alist)
+      (message "Navigation list is now the global bookmark list") (sit-for 2))
+    (unless bmkp-nav-alist (error "No bookmarks in navigation list"))
+    (setq bmkp-current-nav-bookmark  (car bmkp-nav-alist)))
+  (unless (and bmkp-current-nav-bookmark  (not startoverp)
+               (bmkp-get-bookmark bmkp-current-nav-bookmark 'NOERROR))
+    (setq bmkp-current-nav-bookmark  (car bmkp-nav-alist)))
+  (if (bmkp-cycle-1 increment other-window startoverp)
+      (unless (or (bmkp-sequence-bookmark-p bmkp-current-nav-bookmark)
+                  (bmkp-function-bookmark-p bmkp-current-nav-bookmark))
+        (message "Position: %9d, Bookmark: `%s'"
+                 (point) (bmkp-bookmark-name-from-record bmkp-current-nav-bookmark)))
+    (message "Invalid bookmark: `%s'" (bmkp-bookmark-name-from-record bmkp-current-nav-bookmark))))
+
+;;;###autoload (autoload 'bmkp-cycle-other-window "bookmark+")
+(defun bmkp-cycle-other-window (increment &optional startoverp)
+  "Same as `bmkp-cycle' but uses another window."
+  (interactive "p")
+  (bmkp-cycle increment 'OTHER-WINDOW startoverp))
+
+;;;###autoload (autoload 'bmkp-cycle-this-file/buffer "bookmark+")
+(defun bmkp-cycle-this-file/buffer (increment &optional other-window startoverp)
+  "Cycle through bookmarks for this file/buffer by INCREMENT (default: 1).
+If visiting a file, this is `bmkp-cycle-this-file'.
+Otherwise, this is `bmkp-cycle-this-buffer'."
+  (interactive (let ((startovr  (consp current-prefix-arg)))
+                 (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) nil startovr)))
+  (if (buffer-file-name)
+      (bmkp-cycle-this-file increment other-window startoverp)
+    (bmkp-cycle-this-buffer increment other-window startoverp)))
+
+;;;###autoload (autoload 'bmkp-cycle-this-file/buffer-other-window "bookmark+")
+(defun bmkp-cycle-this-file/buffer-other-window (increment &optional startoverp)
+  "Same as `bmkp-cycle-this-file/buffer' but use other window."
+  (interactive (let ((startovr  (consp current-prefix-arg)))
+                 (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr)))
+  (bmkp-cycle-this-file/buffer increment 'OTHER-WINDOW startoverp))
+
+;;;###autoload (autoload 'bmkp-cycle-this-file "bookmark+")
+(defun bmkp-cycle-this-file (increment &optional other-window startoverp)
+  "Cycle through bookmarks for this file by INCREMENT (default: 1).
+Positive INCREMENT cycles forward.  Negative INCREMENT cycles backward.
+Interactively, the prefix arg determines INCREMENT:
+ Plain `C-u': 1
+ otherwise: the numeric prefix arg value
+
+Plain `C-u' also means start over at first bookmark.
+
+You can cycle among bookmarks beyond the current file using
+`bmkp-cycle' and `bmkp-cycle-other-window.'
+
+You can set your preferred sort order for this-file bookmarks by
+customizing option `bmkp-this-file/buffer-cycle-sort-comparer'.
+
+To change the sort order without customizing, you can use \
+`\\[bmkp-this-file-bmenu-list]' to
+show the `*Bookmark List*' with only this file's bookmarks, sort
+them there, and use `\\[bmkp-choose-navlist-from-bookmark-list]', choosing \
+`CURRENT *Bookmark List*' as
+the navigation list.
+
+Then you can cycle the bookmarks using `bmkp-cycle'
+\(`\\[bmkp-next-bookmark-repeat]' etc.), instead of `bmkp-cycle-this-file'.
+
+In Lisp code:
+ Non-nil OTHER-WINDOW means jump to the bookmark in another window.
+ Non-nil STARTOVERP means reset `bmkp-current-nav-bookmark' to the
+ first bookmark in the navlist."
+  (interactive (let ((startovr  (consp current-prefix-arg)))
+                 (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) nil startovr)))
+  (bookmark-maybe-load-default-file)
+  (let ((bmkp-sort-comparer  bmkp-this-file/buffer-cycle-sort-comparer))
+    (setq bmkp-nav-alist  (bmkp-sort-omit (bmkp-this-file-alist-only))))
+  (unless bmkp-nav-alist (error "No bookmarks for this file"))
+  (unless (and bmkp-current-nav-bookmark  (not startoverp)
+               (bmkp-get-bookmark bmkp-current-nav-bookmark 'NOERROR)
+               (bmkp-this-file-p bmkp-current-nav-bookmark)) ; Exclude desktops etc.
+    (setq bmkp-current-nav-bookmark  (car bmkp-nav-alist)))
+  (if (bmkp-cycle-1 increment other-window startoverp)
+      (unless (or (bmkp-sequence-bookmark-p bmkp-current-nav-bookmark)
+                  (bmkp-function-bookmark-p bmkp-current-nav-bookmark))
+        (message "Position: %9d, Bookmark: `%s'"
+                 (point) (bmkp-bookmark-name-from-record bmkp-current-nav-bookmark)))
+    (message "Invalid bookmark: `%s'" (bmkp-bookmark-name-from-record bmkp-current-nav-bookmark))))
+
+;;;###autoload (autoload 'bmkp-cycle-this-file-other-window "bookmark+")
+(defun bmkp-cycle-this-file-other-window (increment &optional startoverp)
+  "Same as `bmkp-cycle-this-file' but use other window."
+  (interactive (let ((startovr  (consp current-prefix-arg)))
+                 (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr)))
+  (bmkp-cycle-this-file increment 'OTHER-WINDOW startoverp))
+
+;;;###autoload (autoload 'bmkp-cycle-this-buffer "bookmark+")
+(defun bmkp-cycle-this-buffer (increment &optional other-window startoverp)
+  "Cycle through bookmarks in this buffer by INCREMENT (default: 1).
+Positive INCREMENT cycles forward.  Negative INCREMENT cycles backward.
+Interactively, the prefix arg determines INCREMENT:
+ Plain `C-u': 1
+ otherwise: the numeric prefix arg value
+
+Plain `C-u' also means start over at first bookmark.
+
+You can cycle among bookmarks beyond the current buffer using
+`bmkp-cycle' and `bmkp-cycle-other-window.'
+
+You can set your preferred sort order for this-buffer bookmarks by
+customizing option `bmkp-this-file/buffer-cycle-sort-comparer'.
+
+To change the sort order without customizing, you can use \
+`\\[bmkp-this-buffer-bmenu-list]' to
+show the `*Bookmark List*' with only this buffer's bookmarks, sort
+them there, and use `\\[bmkp-choose-navlist-from-bookmark-list]', choosing \
+`CURRENT *Bookmark List*' as
+the navigation list.
+
+Then you can cycle the bookmarks using `bmkp-cycle'
+\(`\\[bmkp-next-bookmark-repeat]' etc.), instead of `bmkp-cycle-this-buffer'.
+
+In Lisp code:
+ Non-nil OTHER-WINDOW means jump to the bookmark in another window.
+ Non-nil STARTOVERP means reset `bmkp-current-nav-bookmark' to the
+ first bookmark in the navlist."
+  (interactive (let ((startovr  (consp current-prefix-arg)))
+                 (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) nil startovr)))
+  (bookmark-maybe-load-default-file)
+  (let ((bmkp-sort-comparer  bmkp-this-file/buffer-cycle-sort-comparer))
+    (setq bmkp-nav-alist  (bmkp-sort-omit (bmkp-this-buffer-alist-only))))
+  (unless bmkp-nav-alist (error "No bookmarks in this buffer"))
+  (unless (and bmkp-current-nav-bookmark  (not startoverp)
+               (bmkp-get-bookmark bmkp-current-nav-bookmark 'NOERROR)
+               (bmkp-this-buffer-p bmkp-current-nav-bookmark)) ; Exclude desktops etc.
+    (setq bmkp-current-nav-bookmark  (car bmkp-nav-alist)))
+  (if (bmkp-cycle-1 increment other-window startoverp)
+      (unless (or (bmkp-sequence-bookmark-p bmkp-current-nav-bookmark)
+                  (bmkp-function-bookmark-p bmkp-current-nav-bookmark))
+        (message "Position: %9d, Bookmark: `%s'"
+                 (point) (bmkp-bookmark-name-from-record bmkp-current-nav-bookmark)))
+    (message "Invalid bookmark: `%s'" (bmkp-bookmark-name-from-record bmkp-current-nav-bookmark))))
+
+;;;###autoload (autoload 'bmkp-cycle-this-buffer-other-window "bookmark+")
+(defun bmkp-cycle-this-buffer-other-window (increment &optional startoverp)
+  "Same as `bmkp-cycle-this-buffer' but use other window."
+  (interactive (let ((startovr  (consp current-prefix-arg)))
+                 (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr)))
+  (bmkp-cycle-this-buffer increment 'OTHER-WINDOW startoverp))
+
+(defun bmkp-cycle-1 (increment &optional other-window startoverp)
+  "Helper for `bmkp-cycle*' commands.
+Do nothing if `bmkp-current-nav-bookmark' is an invalid bookmark.
+Return `bmkp-current-nav-bookmark', or nil if invalid.
+
+NOTE: If `pop-up-frames' is non-nil, then cycling inhibits automatic
+showing of annotations (`bookmark-automatically-show-annotations').
+This is to prevent change of frame focus, so cycling can continue
+properly.
+
+See `bmkp-cycle' for descriptions of the arguments."
+  (let ((bookmark-alist   bmkp-nav-alist)
+        (bookmark         (bmkp-get-bookmark bmkp-current-nav-bookmark 'NOERROR))
+        (bmkp-use-region  (eq 'cycling-too bmkp-use-region)))
+    (unless bookmark-alist (error "No bookmarks for cycling"))
+    (when bookmark                      ; Skip bookmarks with bad names.
+      (setq bmkp-current-nav-bookmark
+            (if startoverp
+                (car bookmark-alist)
+              (let ((index  (bmkp-list-position bookmark bookmark-alist #'eq)))
+                (if index
+                    (nth (mod (+ increment index) (length bookmark-alist)) bookmark-alist)
+                  (message "bmkp-cycle-1: Bookmark `%s' is not in navlist"
+                           (bmkp-bookmark-name-from-record bmkp-current-nav-bookmark))
+                  (car bookmark-alist)))))
+      (let ((bookmark-automatically-show-annotations ; Prevent possible frame focus change.
+             (and bookmark-automatically-show-annotations  (not pop-up-frames))))
+        (if other-window
+            (bookmark-jump-other-window (bmkp-bookmark-name-from-record bmkp-current-nav-bookmark))
+          (save-selected-window (bmkp-bookmark-name-from-record (bookmark-jump bmkp-current-nav-bookmark))))))
+    (and bookmark  bmkp-current-nav-bookmark))) ; Return nil if not a valid bookmark.
+
+;; Same as `icicle-list-position' in `icicles-fn.el'.
+;; Simple version of `cl-position' for all Emacs versions.
+(defun bmkp-list-position (item items &optional test)
+  "Find the first occurrence of ITEM in list ITEMS.
+Return the index of the matching item, or nil if not found.
+Items are compared using binary predicate TEST, or `equal' if TEST is
+nil."
+  (unless test (setq test  'equal))
+  (let ((pos  0))
+    (catch 'bmkp-list-position
+      (dolist (itm  items)
+        (when (funcall test item itm) (throw 'bmkp-list-position pos))
+        (setq pos  (1+ pos)))
+      nil)))
+
+;;;###autoload (autoload 'bmkp-next-bookmark "bookmark+")
+(defun bmkp-next-bookmark (n &optional startoverp) ; You can bind this to a repeatable key
+  "Jump to the Nth next bookmark in the bookmark navigation list.
+N defaults to 1, meaning the next bookmark.
+Plain `C-u' means start over at first bookmark.
+See also `bmkp-cycle'."
+  (interactive (let ((startovr  (consp current-prefix-arg)))
+                 (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr)))
+  (bmkp-cycle n nil startoverp))
+
+;;;###autoload (autoload 'bmkp-previous-bookmark "bookmark+")
+(defun bmkp-previous-bookmark (n &optional startoverp) ; You can bind this to a repeatable key
+  "Jump to the Nth previous bookmark in the bookmark navigation list.
+See `bmkp-next-bookmark'."
+  (interactive (let ((startovr  (consp current-prefix-arg)))
+                 (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr)))
+  (bmkp-cycle (- n) nil startoverp))
+
+;;;###autoload (autoload 'bmkp-next-bookmark-other-window "bookmark+")
+(defun bmkp-next-bookmark-other-window (n &optional startoverp) ; You can bind this to a repeatable key
+  "Jump to Nth next bookmark in bookmark navlist in another window.
+N defaults to 1, meaning the next bookmark.
+Plain `C-u' means start over at first bookmark.
+See also `bmkp-cycle'."
+  (interactive (let ((startovr  (consp current-prefix-arg)))
+                 (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr)))
+  (bmkp-cycle n 'OTHER-WINDOW startoverp))
+
+;;;###autoload (autoload 'bmkp-previous-bookmark-other-window "bookmark+")
+(defun bmkp-previous-bookmark-other-window (n &optional startoverp) ; You can bind this to a repeatable key
+  "Jump to Nth previous bookmark in bookmark navlist in another window.
+See `bmkp-next-bookmark'."
+  (interactive (let ((startovr  (consp current-prefix-arg)))
+                 (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr)))
+  (bmkp-cycle (- n) 'OTHER-WINDOW startoverp))
+
+;;;###autoload (autoload 'bmkp-next-bookmark-repeat "bookmark+")
+(defun bmkp-next-bookmark-repeat (arg)  ; `C-x x right', `C-x x f', `C-x x C-f'
+  "Jump to the Nth-next bookmark in the bookmark navigation list.
+This is a repeatable version of `bmkp-next-bookmark'.
+N defaults to 1, meaning the next bookmark.
+Plain `C-u' means start over at the first bookmark (and no repeat)."
+  (interactive "P")
+  (bmkp-repeat-command 'bmkp-next-bookmark))
+
+;;;###autoload (autoload 'bmkp-previous-bookmark-repeat "bookmark+")
+(defun bmkp-previous-bookmark-repeat (arg) ; `C-x x left', `C-x x b', `C-x x C-b'
+  "Jump to the Nth-previous bookmark in the bookmark navigation list.
+See `bmkp-next-bookmark-repeat'."
+  (interactive "P")
+  (bmkp-repeat-command 'bmkp-previous-bookmark))
+
+;;;###autoload (autoload 'bmkp-next-bookmark-other-window-repeat "bookmark+")
+(defun bmkp-next-bookmark-other-window-repeat (arg)  ; `C-x x right', `C-x x f', `C-x x C-f'
+  "Jump to Nth-next bookmark in bookmark navlist in another window.
+This is a repeatable version of `bmkp-next-bookmark'.
+N defaults to 1, meaning the next bookmark.
+Plain `C-u' means start over at the first bookmark (and no repeat)."
+  (interactive "P")
+  (bmkp-repeat-command 'bmkp-next-bookmark-other-window))
+
+;;;###autoload (autoload 'bmkp-previous-bookmark-other-window-repeat "bookmark+")
+(defun bmkp-previous-bookmark-other-window-repeat (arg) ; `C-x x left', `C-x x b', `C-x x C-b'
+  "Jump to Nth-previous bookmark in bookmark navlist in another window.
+See `bmkp-next-bookmark-repeat'."
+  (interactive "P")
+  (bmkp-repeat-command 'bmkp-previous-bookmark-other-window))
+
+;;;###autoload (autoload 'bmkp-next-bookmark-this-file/buffer "bookmark+")
+(defun bmkp-next-bookmark-this-file/buffer (n &optional startoverp) ; Bind to repeatable key, e.g. `S-f2'
+  "Jump to the Nth-next bookmark for the current file/buffer.
+N defaults to 1, meaning the next one.
+Plain `C-u' means start over at the first one.
+See also `bmkp-cycle-this-file/buffer'."
+  (interactive (let ((startovr  (consp current-prefix-arg)))
+                 (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr)))
+  (bmkp-cycle-this-file/buffer n nil startoverp))
+
+;;;###autoload (autoload 'bmkp-previous-bookmark-this-file/buffer "bookmark+")
+(defun bmkp-previous-bookmark-this-file/buffer (n &optional startoverp) ; Bind to repeatable key, e.g. `f2'
+  "Jump to the Nth-previous bookmark for the current file/buffer.
+See `bmkp-next-bookmark-this-file/buffer'."
+  (interactive (let ((startovr  (consp current-prefix-arg)))
+                 (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr)))
+  (bmkp-cycle-this-file/buffer (- n) nil startoverp))
+
+;;;###autoload (autoload 'bmkp-next-bookmark-this-file/buffer-repeat "bookmark+")
+(defun bmkp-next-bookmark-this-file/buffer-repeat (arg)
+                                        ; `C-x x down', `C-x x n', `C-x x C-n', `C-x x mouse-wheel-up'
+  "Jump to the Nth next bookmark for the current file/buffer.
+This is a repeatable version of `bmkp-next-bookmark-this-file/buffer'.
+N defaults to 1, meaning the next one.
+Plain `C-u' means start over at the first one (and no repeat)."
+  (interactive "P")
+  (bmkp-repeat-command 'bmkp-next-bookmark-this-file/buffer))
+
+;;;###autoload (autoload 'bmkp-previous-bookmark-this-file/buffer-repeat "bookmark+")
+(defun bmkp-previous-bookmark-this-file/buffer-repeat (arg)
+                                        ; `C-x x up', `C-x x p', `C-x x C-p', `C-x x mouse-wheel-down'
+  "Jump to the Nth previous bookmark for the current file/buffer.
+See `bmkp-next-bookmark-this-file/buffer-repeat'."
+  (interactive "P")
+  (bmkp-repeat-command 'bmkp-previous-bookmark-this-file/buffer))
+
+;;;###autoload (autoload 'bmkp-next-bookmark-this-file "bookmark+")
+(defun bmkp-next-bookmark-this-file (n &optional startoverp) ; Bind to repeatable key, e.g. `S-f2'
+  "Jump to the Nth-next bookmark for the current file.
+N defaults to 1, meaning the next one.
+Plain `C-u' means start over at the first one.
+See also `bmkp-cycle-this-file'."
+  (interactive (let ((startovr  (consp current-prefix-arg)))
+                 (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr)))
+  (bmkp-cycle-this-file n nil startoverp))
+
+;;;###autoload (autoload 'bmkp-previous-bookmark-this-file "bookmark+")
+(defun bmkp-previous-bookmark-this-file (n &optional startoverp) ; Bind to repeatable key, e.g. `f2'
+  "Jump to the Nth-previous bookmark for the current file.
+See `bmkp-next-bookmark-this-file'."
+  (interactive (let ((startovr  (consp current-prefix-arg)))
+                 (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr)))
+  (bmkp-cycle-this-file (- n) nil startoverp))
+
+;;;###autoload (autoload 'bmkp-next-bookmark-this-file-repeat "bookmark+")
+(defun bmkp-next-bookmark-this-file-repeat (arg)
+  "Jump to the Nth next bookmark for the current file.
+This is a repeatable version of `bmkp-next-bookmark-this-file'.
+N defaults to 1, meaning the next one.
+Plain `C-u' means start over at the first one (and no repeat)."
+  (interactive "P")
+  (bmkp-repeat-command 'bmkp-next-bookmark-this-file))
+
+;;;###autoload (autoload 'bmkp-previous-bookmark-this-file-repeat "bookmark+")
+(defun bmkp-previous-bookmark-this-file-repeat (arg)
+  "Jump to the Nth previous bookmark for the current file.
+See `bmkp-next-bookmark-this-file-repeat'."
+  (interactive "P")
+  (bmkp-repeat-command 'bmkp-previous-bookmark-this-file))
+
+
+;;;###autoload (autoload 'bmkp-next-bookmark-this-buffer "bookmark+")
+(defun bmkp-next-bookmark-this-buffer (n &optional startoverp) ; Bind to repeatable key, e.g. `S-f2'
+  "Jump to the Nth-next bookmark in the current buffer.
+N defaults to 1, meaning the next one.
+Plain `C-u' means start over at the first one.
+See also `bmkp-cycle-this-buffer'."
+  (interactive (let ((startovr  (consp current-prefix-arg)))
+                 (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr)))
+  (bmkp-cycle-this-buffer n nil startoverp))
+
+;;;###autoload (autoload 'bmkp-previous-bookmark-this-buffer "bookmark+")
+(defun bmkp-previous-bookmark-this-buffer (n &optional startoverp) ; Bind to repeatable key, e.g. `f2'
+  "Jump to the Nth-previous bookmark in the current buffer.
+See `bmkp-next-bookmark-this-buffer'."
+  (interactive (let ((startovr  (consp current-prefix-arg)))
+                 (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr)))
+  (bmkp-cycle-this-buffer (- n) nil startoverp))
+
+;;;###autoload (autoload 'bmkp-next-bookmark-this-buffer-repeat "bookmark+")
+(defun bmkp-next-bookmark-this-buffer-repeat (arg)
+  "Jump to the Nth next bookmark in the current buffer.
+This is a repeatable version of `bmkp-next-bookmark-this-buffer'.
+N defaults to 1, meaning the next one.
+Plain `C-u' means start over at the first one (and no repeat)."
+  (interactive "P")
+  (bmkp-repeat-command 'bmkp-next-bookmark-this-buffer))
+
+;;;###autoload (autoload 'bmkp-previous-bookmark-this-buffer-repeat "bookmark+")
+(defun bmkp-previous-bookmark-this-buffer-repeat (arg)
+  "Jump to the Nth previous bookmark in the current buffer.
+See `bmkp-next-bookmark-this-buffer-repeat'."
+  (interactive "P")
+  (bmkp-repeat-command 'bmkp-previous-bookmark-this-buffer))
+
+;;;###autoload (autoload 'bmkp-next-bookmark-w32 "bookmark+")
+(defun bmkp-next-bookmark-w32 (n &optional startoverp)       ; You can bind this to a repeatable key
+  "Windows `Open' the Nth next bookmark in the bookmark navigation list.
+MS Windows only.  Invokes the program associated with the file type.
+N defaults to 1, meaning the next one.
+Plain `C-u' means start over at the first one.
+See also `bmkp-cycle'."
+  (interactive (let ((startovr  (consp current-prefix-arg)))
+                 (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr)))
+  (let ((bmkp-use-w32-browser-p  t))  (bmkp-cycle n nil startoverp)))
+
+;;;###autoload (autoload 'bmkp-previous-bookmark-w32 "bookmark+")
+(defun bmkp-previous-bookmark-w32 (n &optional startoverp)   ; You can bind this to a repeatable key
+  "Windows `Open' the Nth previous bookmark in the bookmark navlist.
+See `bmkp-next-bookmark-w32'."
+  (interactive (let ((startovr  (consp current-prefix-arg)))
+                 (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr)))
+  (let ((bmkp-use-w32-browser-p  t))  (bmkp-cycle (- n) nil startoverp)))
+
+;;;###autoload (autoload 'bmkp-next-bookmark-w32-repeat "bookmark+")
+(defun bmkp-next-bookmark-w32-repeat (arg) ; `C-x x next'
+  "Windows `Open' the Nth next bookmark in the bookmark navigation list.
+This is a repeatable version of `bmkp-next-bookmark'.
+N defaults to 1, meaning the next bookmark.
+Plain `C-u' means start over at the first one (and no repeat)."
+  (interactive "P")
+  (let ((bmkp-use-w32-browser-p  t))  (bmkp-repeat-command 'bmkp-next-bookmark)))
+
+;;;###autoload (autoload 'bmkp-previous-bookmark-w32-repeat "bookmark+")
+(defun bmkp-previous-bookmark-w32-repeat (arg) ; `C-x x prior'
+  "Windows `Open' the Nth previous bookmark in the bookmark navlist.
+See `bmkp-next-bookmark-w32-repeat'."
+  (interactive "P")
+  (let ((bmkp-use-w32-browser-p  t))  (bmkp-repeat-command 'bmkp-previous-bookmark)))
+
+;; In spite of their names, `bmkp-cycle-specific-(buffers|files)*' just cycle bookmarks in the
+;; current buffer or file.  There is no way to choose multiple buffers or files.
+;;
+;; `bmkp-cycle-autonamed', `bmkp-cycle-autonamed-other-window',
+;; `bmkp-cycle-bookmark-list', `bmkp-cycle-bookmark-list-other-window',
+;; `bmkp-cycle-desktop',
+;; `bmkp-cycle-dired', `bmkp-cycle-dired-other-window',
+;; `bmkp-cycle-eww', `bmkp-cycle-eww-other-window',
+;; `bmkp-cycle-file', `bmkp-cycle-file-other-window',
+;; `bmkp-cycle-gnus', `bmkp-cycle-gnus-other-window',
+;; `bmkp-cycle-info', `bmkp-cycle-info-other-window',
+;; `bmkp-cycle-lighted', `bmkp-cycle-lighted-other-window',
+;; `bmkp-cycle-local-file', `bmkp-cycle-local-file-other-window',
+;; `bmkp-cycle-man', `bmkp-cycle-man-other-window',
+;; `bmkp-cycle-non-file', `bmkp-cycle-non-file-other-window',
+;; `bmkp-cycle-remote-file', `bmkp-cycle-remote-file-other-window',
+;; `bmkp-cycle-specific-buffers', `bmkp-cycle-specific-buffers-other-window',
+;; `bmkp-cycle-specific-files', `bmkp-cycle-specific-files-other-window',
+;; `bmkp-cycle-variable-list',
+;; `bmkp-cycle-url', `bmkp-cycle-url-other-window',
+;;
+(bmkp-define-cycle-command "autonamed")
+(bmkp-define-cycle-command "autonamed" 'OTHER-WINDOW)
+(bmkp-define-cycle-command "bookmark-list") ; No other-window version needed
+(bmkp-define-cycle-command "desktop")   ; No other-window version needed
+(bmkp-define-cycle-command "dired")
+(bmkp-define-cycle-command "dired" 'OTHER-WINDOW)
+(bmkp-define-cycle-command "eww")
+(bmkp-define-cycle-command "eww" 'OTHER-WINDOW)
+(bmkp-define-cycle-command "file")
+(bmkp-define-cycle-command "file" 'OTHER-WINDOW)
+(bmkp-define-cycle-command "gnus")
+(bmkp-define-cycle-command "gnus" 'OTHER-WINDOW)
+(bmkp-define-cycle-command "info")
+(bmkp-define-cycle-command "info" 'OTHER-WINDOW)
+(when (featurep 'bookmark+-lit)
+  (bmkp-define-cycle-command "lighted")
+  (bmkp-define-cycle-command "lighted" 'OTHER-WINDOW))
+(bmkp-define-cycle-command "local-file")
+(bmkp-define-cycle-command "local-file" 'OTHER-WINDOW)
+(bmkp-define-cycle-command "man")
+(bmkp-define-cycle-command "man" 'OTHER-WINDOW)
+(bmkp-define-cycle-command "non-file")
+(bmkp-define-cycle-command "non-file" 'OTHER-WINDOW)
+(bmkp-define-cycle-command "remote-file")
+(bmkp-define-cycle-command "remote-file" 'OTHER-WINDOW)
+(bmkp-define-cycle-command "specific-buffers")
+(bmkp-define-cycle-command "specific-buffers" 'OTHER-WINDOW)
+(bmkp-define-cycle-command "specific-files")
+(bmkp-define-cycle-command "specific-files" 'OTHER-WINDOW)
+(bmkp-define-cycle-command "variable-list") ; No other-window version needed
+(bmkp-define-cycle-command "url")
+(bmkp-define-cycle-command "url" 'OTHER-WINDOW)
+
+;; `bmkp-next-autonamed-bookmark', `bmkp-next-autonamed-bookmark-other-window',
+;; `bmkp-next-autonamed-bookmark-repeat', `bmkp-next-autonamed-bookmark-other-window-repeat',
+;; `bmkp-next-bookmark-list-bookmark',
+;; `bmkp-next-bookmark-list-bookmark-repeat',
+;; `bmkp-next-bookmark-list-bookmark-other-window',
+;; `bmkp-next-bookmark-list-bookmark-other-window-repeat',
+;; `bmkp-next-desktop-bookmark',
+;; `bmkp-next-desktop-bookmark-repeat',
+;; `bmkp-next-desktop-bookmark-other-window',
+;; `bmkp-next-desktop-bookmark-other-window-repeat',
+;; `bmkp-next-dired-bookmark',
+;; `bmkp-next-dired-bookmark-repeat',
+;; `bmkp-next-dired-bookmark-other-window',
+;; `bmkp-next-dired-bookmark-other-window-repeat',
+;; `bmkp-next-eww-bookmark',
+;; `bmkp-next-eww-bookmark-repeat',
+;; `bmkp-next-eww-bookmark-other-window',
+;; `bmkp-next-eww-bookmark-other-window-repeat',
+;; `bmkp-next-file-bookmark',
+;; `bmkp-next-file-bookmark-repeat',
+;; `bmkp-next-file-bookmark-other-window',
+;; `bmkp-next-file-bookmark-other-window-repeat',
+;; `bmkp-next-gnus-bookmark',
+;; `bmkp-next-gnus-bookmark-repeat',
+;; `bmkp-next-gnus-bookmark-other-window',
+;; `bmkp-next-gnus-bookmark-other-window-repeat',
+;; `bmkp-next-info-bookmark',
+;; `bmkp-next-info-bookmark-repeat',
+;; `bmkp-next-info-bookmark-other-window',
+;; `bmkp-next-info-bookmark-other-window-repeat',
+;; `bmkp-next-lighted-bookmark',
+;; `bmkp-next-lighted-bookmark-repeat',
+;; `bmkp-next-lighted-bookmark-other-window',
+;; `bmkp-next-lighted-bookmark-other-window-repeat',
+;; `bmkp-next-local-file-bookmark',
+;; `bmkp-next-local-file-bookmark-repeat',
+;; `bmkp-next-local-file-bookmark-other-window',
+;; `bmkp-next-local-file-bookmark-other-window-repeat',
+;; `bmkp-next-man-bookmark',
+;; `bmkp-next-man-bookmark-repeat',
+;; `bmkp-next-man-bookmark-other-window',
+;; `bmkp-next-man-bookmark-other-window-repeat',
+;; `bmkp-next-non-file-bookmark',
+;; `bmkp-next-non-file-bookmark-repeat',
+;; `bmkp-next-non-file-bookmark-other-window',
+;; `bmkp-next-non-file-bookmark-other-window-repeat',
+;; `bmkp-next-remote-file-bookmark',
+;; `bmkp-next-remote-file-bookmark-repeat',
+;; `bmkp-next-remote-file-bookmark-other-window',
+;; `bmkp-next-remote-file-bookmark-other-window-repeat',
+;; `bmkp-next-specific-buffers-bookmark',
+;; `bmkp-next-specific-buffers-bookmark-repeat',
+;; `bmkp-next-specific-buffers-bookmark-other-window',
+;; `bmkp-next-specific-buffers-bookmark-other-window-repeat',
+;; `bmkp-next-specific-files-bookmark',
+;; `bmkp-next-specific-files-bookmark-repeat',
+;; `bmkp-next-specific-files-bookmark-other-window',
+;; `bmkp-next-specific-files-bookmark-other-window-repeat',
+;; `bmkp-next-variable-list-bookmark',
+;; `bmkp-next-variable-list-bookmark-repeat',
+;; `bmkp-next-variable-list-bookmark-other-window',
+;; `bmkp-next-variable-list-bookmark-other-window-repeat',
+;; `bmkp-next-url-bookmark',
+;; `bmkp-next-url-bookmark-repeat'.
+;; `bmkp-next-url-bookmark-other-window',
+;; `bmkp-next-url-bookmark-other-window-repeat'.
+;;
+;; `bmkp-previous-autonamed-bookmark',
+;; `bmkp-previous-autonamed-bookmark-repeat',
+;; `bmkp-previous-autonamed-bookmark-other-window',
+;; `bmkp-previous-autonamed-bookmark-other-window-repeat',
+;; `bmkp-previous-bookmark-list-bookmark',
+;; `bmkp-previous-bookmark-list-bookmark-repeat',
+;; `bmkp-previous-bookmark-list-bookmark-other-window',
+;; `bmkp-previous-bookmark-list-bookmark-other-window-repeat',
+;; `bmkp-previous-desktop-bookmark',
+;; `bmkp-previous-desktop-bookmark-repeat',
+;; `bmkp-previous-desktop-bookmark-other-window',
+;; `bmkp-previous-desktop-bookmark--other-windowrepeat',
+;; `bmkp-previous-dired-bookmark',
+;; `bmkp-previous-dired-bookmark-repeat',
+;; `bmkp-previous-dired-bookmark-other-window',
+;; `bmkp-previous-dired-bookmark-other-window-repeat',
+;; `bmkp-previous-eww-bookmark',
+;; `bmkp-previous-eww-bookmark-repeat',
+;; `bmkp-previous-eww-bookmark-other-window',
+;; `bmkp-previous-eww-bookmark-other-window-repeat',
+;; `bmkp-previous-file-bookmark',
+;; `bmkp-previous-file-bookmark-repeat',
+;; `bmkp-previous-file-bookmark-other-window',
+;; `bmkp-previous-file-bookmark-other-window-repeat',
+;; `bmkp-previous-gnus-bookmark',
+;; `bmkp-previous-gnus-bookmark-repeat',
+;; `bmkp-previous-gnus-bookmark-other-window',
+;; `bmkp-previous-gnus-bookmark-other-window-repeat',
+;; `bmkp-previous-info-bookmark',
+;; `bmkp-previous-info-bookmark-repeat',
+;; `bmkp-previous-info-bookmark-other-window',
+;; `bmkp-previous-info-bookmark-other-window-repeat',
+;; `bmkp-previous-lighted-bookmark',
+;; `bmkp-previous-lighted-bookmark-repeat',
+;; `bmkp-previous-lighted-bookmark-other-window',
+;; `bmkp-previous-lighted-bookmark-other-window-repeat',
+;; `bmkp-previous-local-file-bookmark',
+;; `bmkp-previous-local-file-bookmark-repeat',
+;; `bmkp-previous-local-file-bookmark-other-window',
+;; `bmkp-previous-local-file-bookmark-other-window-repeat',
+;; `bmkp-previous-man-bookmark',
+;; `bmkp-previous-man-bookmark-repeat',
+;; `bmkp-previous-man-bookmark-other-window',
+;; `bmkp-previous-man-bookmark-other-window-repeat',
+;; `bmkp-previous-non-file-bookmark',
+;; `bmkp-previous-non-file-bookmark-repeat',
+;; `bmkp-previous-non-file-bookmark-other-window',
+;; `bmkp-previous-non-file-bookmark-other-window-repeat',
+;; `bmkp-previous-remote-file-bookmark',
+;; `bmkp-previous-remote-file-bookmark-repeat',
+;; `bmkp-previous-remote-file-bookmark-other-window',
+;; `bmkp-previous-remote-file-bookmark--other-windowrepeat',
+;; `bmkp-previous-specific-buffers-bookmark',
+;; `bmkp-previous-specific-buffers-bookmark-repeat',
+;; `bmkp-previous-specific-buffers-bookmark-other-window',
+;; `bmkp-previous-specific-buffers-bookmark-other-window-repeat',
+;; `bmkp-previous-specific-files-bookmark',
+;; `bmkp-previous-specific-files-bookmark-repeat',
+;; `bmkp-previous-specific-files-bookmark-other-window',
+;; `bmkp-previous-specific-files-bookmark-other-window-repeat',
+;; `bmkp-previous-variable-list-bookmark',
+;; `bmkp-previous-variable-list-bookmark-repeat',
+;; `bmkp-previous-variable-list-bookmark-other-window',
+;; `bmkp-previous-variable-list-bookmark-other-window-repeat',
+;; `bmkp-previous-url-bookmark',
+;; `bmkp-previous-url-bookmark-repeat'.
+;; `bmkp-previous-url-bookmark-other-window',
+;; `bmkp-previous-url-bookmark-other-window-repeat'.
+;;
+(bmkp-define-next+prev-cycle-commands "autonamed")
+(bmkp-define-next+prev-cycle-commands "autonamed" 'OTHER-WINDOW)
+(bmkp-define-next+prev-cycle-commands "bookmark-list")
+(bmkp-define-next+prev-cycle-commands "desktop")
+(bmkp-define-next+prev-cycle-commands "dired")
+(bmkp-define-next+prev-cycle-commands "dired" 'OTHER-WINDOW)
+(bmkp-define-next+prev-cycle-commands "eww")
+(bmkp-define-next+prev-cycle-commands "eww" 'OTHER-WINDOW)
+(bmkp-define-next+prev-cycle-commands "file")
+(bmkp-define-next+prev-cycle-commands "file" 'OTHER-WINDOW)
+(bmkp-define-next+prev-cycle-commands "gnus")
+(bmkp-define-next+prev-cycle-commands "gnus" 'OTHER-WINDOW)
+(bmkp-define-next+prev-cycle-commands "info")
+(bmkp-define-next+prev-cycle-commands "info" 'OTHER-WINDOW)
+(bmkp-define-next+prev-cycle-commands "lighted")
+(bmkp-define-next+prev-cycle-commands "lighted" 'OTHER-WINDOW)
+(bmkp-define-next+prev-cycle-commands "local-file")
+(bmkp-define-next+prev-cycle-commands "local-file" 'OTHER-WINDOW)
+(bmkp-define-next+prev-cycle-commands "man")
+(bmkp-define-next+prev-cycle-commands "man" 'OTHER-WINDOW)
+(bmkp-define-next+prev-cycle-commands "non-file")
+(bmkp-define-next+prev-cycle-commands "non-file" 'OTHER-WINDOW)
+(bmkp-define-next+prev-cycle-commands "remote-file")
+(bmkp-define-next+prev-cycle-commands "remote-file" 'OTHER-WINDOW)
+(bmkp-define-next+prev-cycle-commands "specific-buffers")
+(bmkp-define-next+prev-cycle-commands "specific-buffers" 'OTHER-WINDOW)
+(bmkp-define-next+prev-cycle-commands "specific-files")
+(bmkp-define-next+prev-cycle-commands "specific-files" 'OTHER-WINDOW)
+(bmkp-define-next+prev-cycle-commands "variable-list")
+(bmkp-define-next+prev-cycle-commands "url")
+(bmkp-define-next+prev-cycle-commands "url" 'OTHER-WINDOW)
+
+;;;###autoload (autoload 'bmkp-toggle-autonamed-bookmark-set/delete "bookmark+")
+(defun bmkp-toggle-autonamed-bookmark-set/delete (&optional position allp)
+                                        ; Bound globally to `C-x x RET', `C-x x c RET'
+  "If there is an autonamed bookmark at point, delete it, else create one.
+The bookmark created has no region.  Its name is formatted according
+to option `bmkp-autoname-bookmark-function'.
+
+With a prefix arg, delete *ALL* autonamed bookmarks for this buffer.
+
+Non-interactively, act at POSITION, not point.  If nil, act at point."
+  (interactive "d\nP")
+  (unless position (setq position  (point)))
+  (if allp
+      (bmkp-delete-all-autonamed-for-this-buffer)
+    (let ((bmk-name  (funcall bmkp-autoname-bookmark-function position)))
+      (if (not (bmkp-get-bookmark-in-alist bmk-name 'NOERROR))
+          (let ((mark-active  nil))     ; Do not set a region bookmark.
+            (bookmark-set bmk-name)
+            (message "Set bookmark `%s'" bmk-name))
+        (bookmark-delete bmk-name)
+        (message "Deleted bookmark `%s'" bmk-name)))))
+
+;;;###autoload (autoload 'bmkp-set-autonamed-bookmark "bookmark+")
+(defun bmkp-set-autonamed-bookmark (&optional position msg-p)
+  "Set an autonamed bookmark at point.
+The bookmark created has no region.  Its name is formatted according
+to option `bmkp-autoname-bookmark-function'.
+Non-interactively:
+ - Act at POSITION, not point.  If nil, act at point.
+ - Non-nil optional arg MSG-P means display a status message."
+  (interactive (list (point) 'MSG))
+  (unless position (setq position  (point)))
+  (let ((bmk-name     (funcall bmkp-autoname-bookmark-function position))
+        (mark-active  nil))             ; Do not set a region bookmark.
+    (bookmark-set bmk-name)
+    (when msg-p (message "Set bookmark `%s'" bmk-name))))
+
+;;;###autoload (autoload 'bmkp-set-autonamed-bookmark-at-line "bookmark+")
+(defun bmkp-set-autonamed-bookmark-at-line (&optional number)
+  "Set an autonamed bookmark at the beginning of the current line.
+With a prefix arg, set it at the line whose number is the numeric
+prefix value."
+  (interactive (list (and current-prefix-arg  (prefix-numeric-value current-prefix-arg))))
+  (if (not number)
+      (bmkp-set-autonamed-bookmark (line-beginning-position))
+    (save-excursion
+      (goto-char (point-min))
+      (let ((inhibit-field-text-motion  t))
+        (bmkp-set-autonamed-bookmark (line-beginning-position number))))))
+
+(when (> emacs-major-version 21)
+  (defun bmkp-occur-create-autonamed-bookmarks (&optional msg-p) ; Bound to `C-c C-M-B' (aka `C-c C-M-S-b')
+    "Create an autonamed bookmark for each `occur' hit.
+You can use this only in `Occur' mode (commands such as `occur' and
+`multi-occur').
+Non-interactively, non-nil MSG-P means display a status message."
+    (interactive "p")
+    (unless (eq major-mode 'occur-mode) (error "You must be in `occur-mode'"))
+    (let ((count  0))
+      (save-excursion
+        (goto-char (point-min))
+        (while (condition-case nil (progn (occur-next) t) (error nil))
+          (let* ((pos   (get-text-property (point) 'occur-target))
+                 (buf   (and pos  (marker-buffer pos))))
+            (when buf
+              (with-current-buffer buf
+                (goto-char pos)
+                (bmkp-set-autonamed-bookmark (point)))
+              (setq count  (1+ count))))))
+      (when msg-p (message "Created %d autonamed bookmarks" count)))))
+
+;;;###autoload (autoload 'bmkp-set-autonamed-regexp-buffer "bookmark+")
+(defun bmkp-set-autonamed-regexp-buffer (regexp &optional msg-p)
+  "Set autonamed bookmarks at matches for REGEXP in the buffer.
+Non-interactively, non-nil MSG-P means display a status message."
+  (interactive (list (bmkp-read-regexp) 'MSG))
+  (bmkp-set-autonamed-regexp-region regexp (point-min) (point-max) msg-p))
+
+;;;###autoload (autoload 'bmkp-set-autonamed-regexp-region "bookmark+")
+(defun bmkp-set-autonamed-regexp-region (regexp beg end &optional msg-p)
+  "Set autonamed bookmarks at matches for REGEXP in the region.
+Non-interactively, non-nil MSG-P means display a status message."
+  (interactive (list (bmkp-read-regexp) (region-beginning) (region-end) 'MSG))
+  (let ((count  0))
+    (save-excursion
+      (goto-char beg)
+      (while (re-search-forward regexp end t)
+        (bmkp-set-autonamed-bookmark (point))
+        (setq count  (1+ count))
+        (forward-line 1)))
+    (when msg-p (message "Set %d autonamed bookmarks" count))))
+
+(defun bmkp-autoname-bookmark-function-default (position)
+  "Return a bookmark name using POSITION and the current buffer name.
+The name is composed as follows:
+ POSITION followed by a space and then the buffer name.
+ The position value is prefixed with zeros to comprise 9 characters.
+ For example, for POSITION value 31416 and current buffer `my-buffer',
+ the name returned would be `000031416 my-buffer'"
+  (format "%09d %s" (abs position) (buffer-name)))
+
+;;;###autoload (autoload 'bmkp-delete-all-autonamed-for-this-buffer "bookmark+")
+(defun bmkp-delete-all-autonamed-for-this-buffer (&optional msg-p)
+  "Delete all autonamed bookmarks for the current buffer.
+Interactively, or with non-nil arg MSG-P, require confirmation.
+To be deleted, a bookmark name must be an autonamed bookmark whose
+buffer part names the current buffer."
+  (interactive "p")
+  (let ((bmks-to-delete  (mapcar #'bmkp-bookmark-name-from-record
+                                 (bmkp-autonamed-this-buffer-alist-only))))
+    (if (null bmks-to-delete)
+        (when msg-p (message "No autonamed bookmarks for buffer `%s'" (buffer-name)))
+      (when (or (not msg-p)
+                (y-or-n-p (format "Delete ALL autonamed bookmarks for buffer `%s'? " (buffer-name))))
+        (let ((bookmark-save-flag   (and (not bmkp-count-multi-mods-as-one-flag)
+                                         bookmark-save-flag))) ; Save at most once, after `dolist'.
+          (dolist (bmk  bmks-to-delete)  (bookmark-delete bmk 'BATCHP))) ; No refresh yet.
+        (bmkp-refresh/rebuild-menu-list nil (not msg-p)) ; Now refresh, after iterate.
+        (when msg-p (message "Deleted all bookmarks for buffer `%s'" (buffer-name)))))))
+
+;; You can use this in `kill-buffer-hook'.
+(defun bmkp-delete-autonamed-this-buffer-no-confirm (&optional no-refresh-p)
+  "Delete all autonamed bookmarks for this buffer, without confirmation.
+Non-nil optional arg NO-REFRESH-P means do not refresh/rebuild the
+bookmark-list."
+  (when (and bookmarks-already-loaded  bookmark-alist)
+    (let ((bmks-to-delete      (mapcar #'bmkp-bookmark-name-from-record
+                                       (bmkp-autonamed-this-buffer-alist-only)))
+          (bookmark-save-flag  (and (not bmkp-count-multi-mods-as-one-flag)
+                                    bookmark-save-flag))) ; Save at most once, after `dolist'.
+      (dolist (bmk  bmks-to-delete)  (bookmark-delete bmk 'BATCHP))) ; No refresh yet.
+    (unless no-refresh-p
+      (bmkp-refresh/rebuild-menu-list nil 'BATCHP)))) ; Now refresh, after iterate.
+
+
+;; You can use this in `kill-emacs-hook'.
+(defun bmkp-delete-autonamed-no-confirm ()
+  "Delete all autonamed bookmarks for all buffers, without confirmation."
+  (when (and bookmarks-already-loaded  bookmark-alist)
+    (let ((bookmark-save-flag  (and (not bmkp-count-multi-mods-as-one-flag)
+                                    bookmark-save-flag))) ; Save at most once, after `dolist'.
+      (dolist (buf  (buffer-list))
+        (with-current-buffer buf
+          (bmkp-delete-autonamed-this-buffer-no-confirm 'NO-REFRESH-P)))) ; No refresh yet.
+    (bmkp-refresh/rebuild-menu-list nil 'BATCHP))) ; Now refresh, after iterate.
+
+(cond ((fboundp 'define-minor-mode)
+       ;; Emacs 21 and later.  Eval this so that even if the library is byte-compiled with Emacs 20,
+       ;; loading it into Emacs 21+ will define variable `bmkp-automatic-bookmark-mode'.
+       (eval '(define-minor-mode bmkp-automatic-bookmark-mode
+               "Toggle automatic setting of a bookmark when Emacs is idle.
+Non-interactively, turn automatic bookmarking on for the current
+buffer if and only if ARG is positive.
+
+To enable or disable automatic bookmarking in all buffers, use
+`bmkp-global-automatic-bookmark-mode'.
+
+When the mode is enabled in the current buffer, a bookmark is
+automatically set every `bmkp-automatic-bookmark-mode-delay' seconds,
+using the setting function that is the value of option
+`bmkp-automatic-bookmark-set-function'.  Note that a buffer must be
+current (selected) for an automatic bookmark to be created there - it
+is not enough that the mode be enabled in the buffer.
+
+Turning the mode on and off runs hooks
+`bmkp-automatic-bookmark-mode-on-hook' and
+`bmkp-automatic-bookmark-mode-off-hook', respectively.
+
+If you want the automatic bookmarks to be temporary (not saved to your
+bookmark file), then customize option
+`bmkp-autotemp-bookmark-predicates' so that it includes the kind of
+bookmarks that are set by `bmkp-automatic-bookmark-set-function'.
+For example, if automatic bookmarking sets autonamed bookmarks, then
+`bmkp-autotemp-bookmark-predicates' should include
+`bmkp-autonamed-bookmark-p' or
+`bmkp-autonamed-this-buffer-bookmark-p'.
+
+If you want the automatically created bookmarks to be highlighted,
+then customize option `bmkp-auto-light-when-set' to highlight
+bookmarks of the appropriate kind.  For example, to highlight
+autonamed bookmarks set it to `autonamed-bookmark'.
+
+NOTE: If you use Emacs 21 then there is no global version of the mode
+- that is, there is no command `bmkp-global-automatic-bookmark-mode'."
+               :init-value nil :group 'bookmark-plus :require 'bookmark+
+               :lighter bmkp-automatic-bookmark-mode-lighter
+               :link `(url-link :tag "Send Bug Report"
+                       ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\
+Bookmark bug: \
+&body=Describe bug here, starting with `emacs -Q'.  \
+Don't forget to mention your Emacs and library versions."))
+               :link '(url-link :tag "Download" "https://www.emacswiki.org/emacs/download/bookmark%2b.el")
+               :link '(url-link :tag "Description" "https://www.emacswiki.org/emacs/BookmarkPlus")
+               :link '(emacs-commentary-link :tag "Commentary" "bookmark+")
+               (when bmkp-automatic-bookmark-mode-timer
+                 (cancel-timer bmkp-automatic-bookmark-mode-timer)
+                 (setq bmkp-automatic-bookmark-mode-timer  nil))
+               (when bmkp-automatic-bookmark-mode
+                 (setq bmkp-automatic-bookmark-mode-timer
+                       (run-with-idle-timer bmkp-automatic-bookmark-mode-delay 'REPEAT
+                                            (lambda ()
+                                              (when bmkp-automatic-bookmark-mode
+                                                (bmkp-set-automatic-bookmark))))))
+               (when (interactive-p)
+                 (message "Automatic bookmarking is now %s in buffer `%s'"
+                          (if bmkp-automatic-bookmark-mode "ON" "OFF") (buffer-name)))))
+
+       (eval '(defun bmkp-turn-on-automatic-bookmark-mode ()
+               "Turn on `bmkp-automatic-bookmark-mode'."
+               (bmkp-automatic-bookmark-mode 1)))
+
+       (when (fboundp 'define-globalized-minor-mode) ; Emacs 22+, not 21.
+         (eval '(define-globalized-minor-mode bmkp-global-automatic-bookmark-mode
+                 bmkp-automatic-bookmark-mode
+                 bmkp-turn-on-automatic-bookmark-mode
+                 :group 'bookmark-plus :require 'bookmark+))))
+      (t                                ; Emacs 20.
+       (defun bmkp-automatic-bookmark-mode (&optional arg)
+         "Toggle automatic setting of a bookmark when Emacs is idle.
+Non-interactively, turn automatic bookmarking on if and only if ARG is
+positive.
+
+When the mode is enabled, a bookmark is automatically set every
+`bmkp-automatic-bookmark-mode-delay' seconds, using the setting
+function that is the value of option
+`bmkp-automatic-bookmark-set-function'.  Note that a buffer must be
+current (selected) for an automatic bookmark to be created there - it
+is not enough that the mode be enabled in the buffer.
+
+If you want these bookmarks to be temporary (not saved to your
+bookmark file), then customize option
+`bmkp-autotemp-bookmark-predicates' so that it includes the kind of
+bookmarks that are set by `bmkp-automatic-bookmark-set-function'.  For
+example, if automatic bookmarking sets autonamed bookmarks, then
+`bmkp-autotemp-bookmark-predicates' should include
+`bmkp-autonamed-bookmark-p'.
+
+If you want the automatically created bookmarks to be highlighted,
+then customize option `bmkp-auto-light-when-set' to highlight
+bookmarks of the appropriate kind.  For example, to highlight
+autonamed bookmarks set it to `autonamed-bookmark'.
+
+NOTE: This is the Emacs 20 version of `bmkp-automatic-bookmark-mode',
+which is global only, that is, all buffers are affected.  If you
+instead want it to be local only, then do both of the following in
+your init file:
+  (make-variable-buffer-local 'bmkp-automatic-bookmark-mode)
+  (make-variable-buffer-local 'bmkp-automatic-bookmark-mode-timer)"
+         (interactive (list (or current-prefix-arg  'toggle)))
+         (setq bmkp-automatic-bookmark-mode  (if (eq arg 'toggle)
+                                                 (not bmkp-automatic-bookmark-mode)
+                                               (> (prefix-numeric-value arg) 0)))
+         (when bmkp-automatic-bookmark-mode-timer
+           (cancel-timer bmkp-automatic-bookmark-mode-timer)
+           (setq bmkp-automatic-bookmark-mode-timer  nil))
+         (when bmkp-automatic-bookmark-mode
+           (setq bmkp-automatic-bookmark-mode-timer
+                 (run-with-idle-timer bmkp-automatic-bookmark-mode-delay 'REPEAT
+                                      (lambda () ; This allows use as a local mode.
+                                        (when bmkp-automatic-bookmark-mode (bmkp-set-automatic-bookmark))))))
+         (when (interactive-p)
+           (message "Automatic bookmarking is now %s%s"
+                    (if bmkp-automatic-bookmark-mode "ON" "OFF")
+                    (if (local-variable-if-set-p 'bmkp-automatic-bookmark-mode)
+                        (format " in buffer `%s'" (current-buffer))
+                      ""))))
+
+
+       (add-to-list 'minor-mode-alist `(bmkp-automatic-bookmark-mode
+                                        ,bmkp-automatic-bookmark-mode-lighter))))
+
+(defun bmkp-not-near-other-automatic-bmks (&optional position)
+  "Is POSITION far enough from automatic bookmarks to create a new one?
+Return non-nil if `bmkp-automatic-bookmark-min-distance' is nil or if
+POSITION is at least `bmkp-automatic-bookmark-min-distance' chars from
+all other automatic bookmarks in the same buffer.  Else return nil."
+  (unless position (setq position  (point)))
+  (or (not bmkp-automatic-bookmark-min-distance)
+      (catch 'bmkp-not-near-other-automatic-bmks
+        (let (bmk-pos)
+          (dolist (bmk  bmkp-automatic-bookmarks)
+            (when (and (bmkp-this-buffer-p bmk)
+                       (setq bmk-pos  (bookmark-get-position bmk))
+                       (or (not bmk-pos)  (< (abs (- position bmk-pos)) bmkp-automatic-bookmark-min-distance)))
+              (throw 'bmkp-not-near-other-automatic-bmks nil)))
+          t))))
+
+(defun bmkp-set-automatic-bookmark ()
+  "Invoke `bmkp-automatic-bookmark-set-function'.
+Do nothing if bookmark would be too near another automatic bookmark."
+  (when (bmkp-not-near-other-automatic-bmks)
+    (let ((bmkp-setting-automatic-bmk-p  t)) (funcall bmkp-automatic-bookmark-set-function))))
+
+(when (> emacs-major-version 21)        ; Emacs 22+ (need also `Info-selection-hook').
+
+  ;; Eval this so that even if the library is byte-compiled with Emacs 20,
+  ;; loading it into Emacs 22+ will define variable `bmkp-info-auto-bookmark-mode'.
+  (eval '(define-minor-mode bmkp-info-auto-bookmark-mode
+          "Toggle automatically setting a bookmark when you visit an Info node.
+The bookmark name is \"(MANUAL) `NODE'\", where:
+
+ MANUAL is the name of the current manual (the base file name).
+ NODE is the name of the current node.
+
+If option `bmkp-info-auto-type' is `create-or-update' then such a
+bookmark is created for the node if none exists.  If the option value
+is `update-only' then no new bookmark is created automatically, but an
+existing bookmark is updated.  (Updating a bookmark increments the
+recorded number of visits.)  You can toggle the option using
+`\\[bmkp-toggle-info-auto-type]'."
+          :init-value nil :global t :group 'bookmark-plus :require 'bookmark+
+          :lighter bmkp-automatic-bookmark-mode-lighter
+          :link `(url-link :tag "Send Bug Report"
+                  ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\
+Bookmark bug: \
+&body=Describe bug here, starting with `emacs -Q'.  \
+Don't forget to mention your Emacs and library versions."))
+          :link '(url-link :tag "Download" "https://www.emacswiki.org/emacs/download/bookmark%2b.el")
+          :link '(url-link :tag "Description" "https://www.emacswiki.org/emacs/BookmarkPlus")
+          :link '(emacs-commentary-link :tag "Commentary" "bookmark+")
+          (if bmkp-info-auto-bookmark-mode
+              (add-hook 'Info-selection-hook 'bmkp-set-info-bookmark-with-node-name)
+            (remove-hook 'Info-selection-hook 'bmkp-set-info-bookmark-with-node-name))
+          (when (interactive-p)
+            (message "Automatic Info bookmarking is now %s" (if bmkp-info-auto-bookmark-mode "ON" "OFF")))))
+
+  (defun bmkp-set-info-bookmark-with-node-name (&optional nomsg)
+    "Maybe bookmark the current Info node using name \"(MANUAL) `NODE'\".
+MANUAL is the name of the current manual (the base file name).
+NODE is the name of the current node.
+
+If option `bmkp-info-auto-type' is `create-or-update' then a bookmark
+is created for the node if none exists.  If it is `update-only' then
+no new bookmark is created automatically, but an existing bookmark is
+updated.  You can use toggle `bmkp-info-auto-type' using
+`\\[bmkp-toggle-info-auto-type]'.
+
+Non-nil optional arg NOMSG means do not display a message saying that
+the node was bookmarked."
+    (interactive)
+    (when (and (derived-mode-p 'Info-mode)  Info-current-node)
+      (save-excursion
+        (goto-char (point-min))
+        (let* ((bmk-name  (and (stringp Info-current-file)
+                               (format "(%s) %s" (file-name-sans-extension
+                                                  (file-name-nondirectory Info-current-file))
+                                       Info-current-node)))
+               (bmk       (bmkp-bookmark-record-from-name bmk-name 'NOERROR))
+               (visits    (and bmk  (bookmark-prop-get bmk 'visits))))
+          (when bmk-name
+            (cond ((and (not visits)  (eq bmkp-info-auto-type 'create-or-update))
+                   (bookmark-set bmk-name)
+                   (unless nomsg (message "Created bookmark `%s' for Info node" bmk-name)))
+                  (visits
+                   (bmkp-record-visit bmk-name 'BATCHP)
+                   (bmkp-refresh/rebuild-menu-list bmk-name nil)
+                   (bmkp-maybe-save-bookmarks)
+                   (unless nomsg (message "Updated bookmark `%s' for Info node" bmk-name)))))))))
+
+  (defun bmkp-toggle-info-auto-type (&optional msgp)
+    "Toggle the value of option `bmkp-info-auto-type'."
+    (interactive "p")
+    (setq bmkp-info-auto-type  (if (eq bmkp-info-auto-type 'create-or-update) 'update-only 'create-or-update))
+    (when msgp (message "`bmkp-info-auto-bookmark-mode' now %s" 
+                        (if (eq bmkp-info-auto-type 'create-or-update)
+                            "CREATES, as well as updates, Info bookmarks"
+                          "only UPDATES EXISTING Info bookmarks"))))
+
+  )
+
+(if (fboundp 'define-minor-mode)
+    ;; Emacs 21 and later.  Eval this so that even if the library is byte-compiled with Emacs 20,
+    ;; loading it into Emacs 21+ will define variable `bmkp-temporary-bookmarking-mode'.
+    (eval '(define-minor-mode bmkp-temporary-bookmarking-mode ; `M-L' in `*Bookmark List*'.
+            "Toggle temporary bookmarking.
+Temporary bookmarking means that any bookmark changes (creation,
+modification, deletion) are NOT automatically saved.
+
+Interactively, you are required to confirm turning on the mode.
+
+When the mode is turned ON:
+ a. `bookmark-save-flag' is set to nil.
+ b. `bmkp-current-bookmark-file' is set to a new, empty bookmark file
+    in directory `temporary-file-directory' (via `make-temp-file').
+ c. That file is not saved automatically.
+ d. In the `*Bookmark List*' display, the major-mode mode-line
+    indicator is set to `TEMPORARY ONLY'.
+
+Non-interactively, turn temporary bookmarking on if and only if ARG is
+positive.  Non-interactively there is no prompt for confirmation."
+            :init-value nil :global t :group 'bookmark-plus :lighter bmkp-temporary-bookmarking-mode-lighter
+            :link `(url-link :tag "Send Bug Report"
+                    ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\
+Bookmark bug: \
+&body=Describe bug here, starting with `emacs -Q'.  \
+Don't forget to mention your Emacs and library versions."))
+            :link '(url-link :tag "Download" "https://www.emacswiki.org/emacs/download/bookmark%2b.el")
+            :link '(url-link :tag "Description" "https://www.emacswiki.org/emacs/BookmarkPlus")
+            :link '(emacs-commentary-link :tag "Commentary" "bookmark+")
+            (cond ((not bmkp-temporary-bookmarking-mode) ; Turn off.
+                   (when (fboundp 'bmkp-unlight-bookmarks) ; In `bookmark+-lit.el'.
+                     (bmkp-unlight-bookmarks ; Unhighlight the temporary (current) bookmarks.
+                      '(bmkp-autonamed-overlays bmkp-non-autonamed-overlays) nil))
+                   (bmkp-switch-to-last-bookmark-file)
+                   (setq bmkp-last-bookmark-file  bmkp-current-bookmark-file) ; Forget last (temp file).
+                   (when (interactive-p)
+                     (message "Bookmarking is NOT temporary now.  Restored previous bookmarks list")))
+                  ((or (not (interactive-p))
+                       (y-or-n-p (format "%switch to only temporary bookmarking? "
+                                         (if bookmark-save-flag "Save current bookmarks, then s" "S"))))
+                   (when (and (> bookmark-alist-modification-count 0)  bookmark-save-flag)
+                     (bookmark-save))
+                   (let ((new-file  (make-temp-file "bmkp-temp-")))
+                     (with-current-buffer (let ((enable-local-variables  ())) (find-file-noselect new-file))
+                       (goto-char (point-min))
+                       (delete-region (point-min) (point-max)) ; In case a find-file hook inserted a header.
+                       (if (boundp 'bookmark-file-coding-system) ; Emacs 25.2+
+                           (bookmark-insert-file-format-version-stamp bookmark-file-coding-system)
+                         (bookmark-insert-file-format-version-stamp))
+                       (insert "(\n)"))
+                     (bmkp-empty-file new-file)
+                     (setq bmkp-last-as-first-bookmark-file  nil) ; Prevent starting from a file of temp bmks.
+                     (bookmark-load new-file t 'nosave) ; Saving was done just above.
+                     (when bookmark-save-flag (bmkp-toggle-saving-bookmark-file (interactive-p))))
+                   (when (interactive-p) (message "Bookmarking is now TEMPORARY")))
+                  (t                    ; User refused to confirm.
+                   (message "OK, canceled - bookmarking is NOT temporary")
+                   (setq bmkp-temporary-bookmarking-mode  nil)))))
+
+  ;; Emacs 20
+  (defun bmkp-temporary-bookmarking-mode (&optional arg) ; `M-L' in `*Bookmark List*'.
+    "Toggle temporary bookmarking.
+Temporary bookmarking means that any bookmark changes (creation,
+modification, deletion) are NOT automatically saved.
+
+Interactively, you are required to confirm turning on the mode.
+
+When the mode is turned ON:
+ a. `bookmark-save-flag' is set to nil.
+ b. `bmkp-current-bookmark-file' is set to a new, empty bookmark file
+    in directory `temporary-file-directory' (via `make-temp-file').
+ c. That file is not saved automatically.
+ d. In the `*Bookmark List*' display, the major-mode mode-line
+    indicator is set to `TEMPORARY ONLY'.
+
+Non-interactively, turn temporary bookmarking on if and only if ARG is
+positive.  Non-interactively there is no prompt for confirmation."
+    (interactive "P")
+    (setq bmkp-temporary-bookmarking-mode
+          (if arg (> (prefix-numeric-value arg) 0) (not bmkp-temporary-bookmarking-mode)))
+    (cond ((not bmkp-temporary-bookmarking-mode) ; Turn off.
+           (when (fboundp 'bmkp-unlight-bookmarks) ; In `bookmark+-lit.el'.
+             (bmkp-unlight-bookmarks    ; Unhighlight the temporary (current) bookmarks.
+              '(bmkp-autonamed-overlays bmkp-non-autonamed-overlays) nil))
+           (bmkp-switch-to-last-bookmark-file)
+           (setq bmkp-last-bookmark-file  bmkp-current-bookmark-file) ; Forget last (temporary file).
+           (run-hooks 'bmkp-temporary-bookmarking-mode-hook)
+           (when (interactive-p)
+             (message "Bookmarking is NOT temporary now.  Restored previous bookmarks list")))
+          ((or (not (interactive-p))
+               (y-or-n-p (format "%switch to only TEMPORARY bookmarking? "
+                                 (if bookmark-save-flag "Save current bookmarks, then s" "S"))))
+           (when (and (> bookmark-alist-modification-count 0)  bookmark-save-flag)
+             (bookmark-save))
+           (let ((new-file  (make-temp-file "bmkp-temp-")))
+             (with-current-buffer (let ((enable-local-variables  ())) (find-file-noselect new-file))
+               (goto-char (point-min))
+               (delete-region (point-min) (point-max)) ; In case a find-file hook inserted a header, etc.
+               (bookmark-insert-file-format-version-stamp)
+               (insert "(\n)"))
+             (bmkp-empty-file new-file)
+             (bookmark-load new-file t 'nosave) ; Saving was done just above.
+             (when bookmark-save-flag (bmkp-toggle-saving-bookmark-file (interactive-p))))
+           (run-hooks 'bmkp-temporary-bookmarking-mode-hook)
+           (when (interactive-p) (message "Bookmarking is now TEMPORARY")))
+          (t                            ; User refused to confirm.
+           (message "OK, canceled - bookmarking is NOT temporary")
+           (setq bmkp-temporary-bookmarking-mode  nil))))
+
+
+  (add-to-list 'minor-mode-alist `(bmkp-temporary-bookmarking-mode
+                                   ,bmkp-temporary-bookmarking-mode-lighter)))
+
+;;;###autoload (autoload 'bmkp-toggle-autotemp-on-set "bookmark+")
+(defun bmkp-toggle-autotemp-on-set (&optional msg-p) ; Bound to `C-x x x'
+  "Toggle automatically making any bookmark temporary whenever it is set.
+Non-interactively, non-nil MSG-P means display a status message."
+  (interactive "p")
+  (setq bmkp-autotemp-all-when-set-p  (not bmkp-autotemp-all-when-set-p))
+  (when msg-p (message "Automatically making bookmarks temporary when set is now %s"
+                       (if bmkp-autotemp-all-when-set-p "ON" "OFF"))))
+
+;;;###autoload (autoload 'bmkp-toggle-temporary-bookmark "bookmark+")
+(defun bmkp-toggle-temporary-bookmark (bookmark &optional msg-p)
+  "Toggle whether BOOKMARK is temporary (not saved to disk).
+Return the full updated bookmark.
+BOOKMARK is a bookmark name or a bookmark record.
+Non-interactively, non-nil MSG-P means display a status message."
+  (interactive (list (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name)) 'MSG))
+  (let ((was-temp  (bmkp-temporary-bookmark-p bookmark)))
+    (bookmark-prop-set bookmark 'bmkp-temp (not was-temp))
+    (when msg-p (message "Bookmark `%s' is now %s"
+                         (if (stringp bookmark) bookmark (bmkp-bookmark-name-from-record bookmark))
+                         (if was-temp "SAVABLE" "TEMPORARY"))))
+  bookmark)
+
+;;;###autoload (autoload 'bmkp-make-bookmark-temporary "bookmark+")
+(defun bmkp-make-bookmark-temporary (bookmark &optional msg-p)
+  "Make BOOKMARK temporary (not saved to disk).
+Return the full updated bookmark.
+BOOKMARK is a bookmark name or a bookmark record.
+Non-interactively, non-nil MSG-P means display a status message."
+  (interactive (list (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name)) 'MSG))
+  (bookmark-prop-set bookmark 'bmkp-temp t)
+  (when msg-p (message "Bookmark `%s' is now TEMPORARY"
+                       (if (stringp bookmark) bookmark (bmkp-bookmark-name-from-record bookmark))))
+  bookmark)
+
+;;;###autoload (autoload 'bmkp-make-bookmark-savable "bookmark+")
+(defun bmkp-make-bookmark-savable (bookmark &optional msg-p)
+  "Make BOOKMARK savable to disk (not temporary).
+Return the full updated bookmark.
+BOOKMARK is a bookmark name or a bookmark record.
+Non-interactively, non-nil MSG-P means display a status message."
+  (interactive (list (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name)) 'MSG))
+  (bookmark-prop-set bookmark 'bmkp-temp nil)
+  (when msg-p (message "Bookmark `%s' is now SAVABLE"
+                       (if (stringp bookmark) bookmark (bmkp-bookmark-name-from-record bookmark))))
+  bookmark)
+
+;;;###autoload (autoload 'bmkp-delete-all-temporary-bookmarks "bookmark+")
+(defun bmkp-delete-all-temporary-bookmarks (&optional msg-p)
+  "Delete all temporary bookmarks, after confirmation.
+These are bookmarks that are `bmkp-temporary-bookmark-p'.  You can
+make a bookmark temporary using `bmkp-make-bookmark-temporary' or
+`bmkp-toggle-temporary-bookmark'.
+Non-interactively, non-nil MSG-P means display a status message."
+  (interactive "p")
+  (let ((bmks-to-delete  (mapcar #'bmkp-bookmark-name-from-record (bmkp-temporary-alist-only))))
+    (if (null bmks-to-delete)
+        (when msg-p (message "No temporary bookmarks to delete"))
+      (when (and msg-p  (not (y-or-n-p (format "Delete ALL temporary bookmarks? "))))
+        (error "OK - delete canceled"))
+      (let ((bookmark-save-flag  (and (not bmkp-count-multi-mods-as-one-flag)
+                                      bookmark-save-flag))) ; Save at most once, after `dolist'.
+        (dolist (bmk  bmks-to-delete)  (bookmark-delete bmk 'BATCHP))) ; No refresh yet.
+      (bmkp-refresh/rebuild-menu-list nil (not msg-p)) ; Now refresh, after iterate.
+      (when msg-p (message "Deleted all temporary bookmarks")))))
+
+;; You can use this in `kill-emacs-hook'.
+(defun bmkp-delete-temporary-no-confirm ()
+  "Delete all temporary bookmarks, without confirmation."
+  (when (and bookmarks-already-loaded  bookmark-alist)
+    (let ((bmks-to-delete  (mapcar #'bmkp-bookmark-name-from-record (bmkp-temporary-alist-only)))
+          (bookmark-save-flag  (and (not bmkp-count-multi-mods-as-one-flag)
+                                    bookmark-save-flag))) ; Save at most once, after `dolist'.
+      (dolist (bmk  bmks-to-delete)  (bookmark-delete bmk 'BATCHP))) ; No refresh yet.
+    (bmkp-refresh/rebuild-menu-list nil 'BATCHP))) ; Now refresh, after iterate.
+
+;;;###autoload (autoload 'bmkp-delete-bookmarks "bookmark+")
+(defun bmkp-delete-bookmarks (&optional position allp alist msg-p) ; Bound to `C-x x delete'
+  "Delete some bookmarks at point or all bookmarks in the buffer.
+With no prefix argument, delete some bookmarks at point.
+If there is more than one, require confirmation for each.
+
+With a prefix argument, delete *ALL* bookmarks in the current buffer.
+
+Non-interactively:
+* Delete at POSITION, not point.  If nil, delete at point.
+* Non-nil optional arg ALLP means delete all bookmarks in the buffer.
+* ALIST is the alist of bookmarks.
+  If nil, use the bookmarks in the current buffer.
+* Non-nil MSG-P means display informative messages."
+  (interactive "d\nP\ni\np")
+  (unless position (setq position  (point)))
+  (let ((bmks-to-delete  (and allp  (mapcar #'bmkp-bookmark-name-from-record (bmkp-this-buffer-alist-only))))
+        (bmks-deleted    ())
+        bmk-pos)
+    (when (and msg-p  bmks-to-delete  (not (y-or-n-p (format "Delete ALL bookmarks in buffer `%s'? "
+                                                             (buffer-name)))))
+      (error "Canceled - no bookmarks deleted"))
+    (cond (bmks-to-delete               ; Delete all.
+           (let ((bookmark-save-flag  (and (not bmkp-count-multi-mods-as-one-flag)
+                                           bookmark-save-flag))) ; Save at most once, after `dolist'.
+             (dolist (bname  bmks-to-delete) (bookmark-delete bname 'BATCHP))) ; No refresh yet.
+           (bmkp-refresh/rebuild-menu-list nil (not msg-p)) ; Refresh now, after iterate.
+           (when msg-p (message "Deleted all bookmarks in buffer `%s'" (buffer-name))))
+
+          (allp                         ; Requested ALLP, but there are none.  (No-op if not interactive.)
+           (when msg-p (message "No bookmarks to delete in buffer `%s'" (buffer-name))))
+
+          (t                            ; Delete selected bookmarks at point.
+           (let (bname)
+             (dolist (bmk  (or alist  (bmkp-this-buffer-alist-only)))
+               (when (eq position (setq bmk-pos  (bookmark-get-position bmk)))
+                 (setq bname  (bmkp-bookmark-name-from-record bmk))
+                 ;; This is the same as `add-to-list' with `EQ' (not available for Emacs 20-21).
+                 (unless (memq bname bmks-to-delete)
+                   (setq bmks-to-delete  (cons bname bmks-to-delete)))))
+             (cond ((cadr bmks-to-delete) ; More than one at point.
+                    (let ((bookmark-save-flag  (and (not bmkp-count-multi-mods-as-one-flag)
+                                                    bookmark-save-flag))) ; Save at most once, after `dolist'.
+                      (dolist (bname  bmks-to-delete)
+                        (when (or (not msg-p)  (y-or-n-p (format "Delete bookmark `%s'? " bname)))
+                          (bookmark-delete bname 'BATCHP) ; No refresh yet.
+                          ;; This is the same as `add-to-list' with `EQ' (not available for Emacs 20-21).
+                          (unless (memq bname bmks-deleted) (setq bmks-deleted  (cons bname bmks-deleted))))))
+                    (bmkp-refresh/rebuild-menu-list nil (not msg-p)) ; Refresh now.
+                    (when msg-p
+                      (message (if bmks-deleted
+                                   (format "Deleted bookmarks: %s"
+                                           (mapconcat (lambda (bname) (format "`%s'" bname)) bmks-deleted
+                                                      ", "))
+                                 "No bookmarks deleted"))))
+                   (bmks-to-delete      ; Only one bookmark at point.
+                    (bookmark-delete (car bmks-to-delete))
+                    (when msg-p (message "Deleted bookmark `%s'" (car bmks-to-delete))))
+                   (t
+                    (when msg-p (message "No bookmarks at point to delete")))))))))
+
+;; Because of Emacs bug #19915, we need to use `advice-add' for `org-store-link', so this feature
+;; is available only for Emacs 24.4+.
+(when (fboundp 'advice-add)
+             
+  (defvar bmkp-store-org-link-checking-p nil
+    "Whether `bmkp-(bmenu-)store-org-link(-1)' call is checking applicability.")
+
+  (defun bmkp-store-org-link (arg)
+    "Store a link to a bookmark for insertion in an Org-mode buffer.
+You are prompted for the bookmark name.
+
+If you use a numeric prefix arg then the bookmark will be jumped to in
+the same window.  Without a numeric prefix arg, the link will use
+another window.  The link type is `bookmark' or `bookmark-other-win',
+respectively."
+    (interactive "P")
+    (require 'org)
+    (let ((org-store-link-functions  (append org-store-link-functions '(bmkp-store-org-link-1))))
+      (call-interactively #'org-store-link)))
+
+  (defun bmkp-store-org-link-1 ()
+    "Store a link to a bookmark for insertion in an Org-mode buffer.
+See command `bmkp-store-org-link'."
+    (setq bmkp-store-org-link-checking-p  (not bmkp-store-org-link-checking-p))
+    (require 'org)
+    (or bmkp-store-org-link-checking-p  ; Non-nil return is all that is needed for checking.
+        (let* ((other-win  (and current-prefix-arg  (not (consp current-prefix-arg))))
+               (bmk        (bmkp-completing-read-lax
+                            (format "Store %sOrg link for bookmark" (if other-win "other-window " ""))))
+               (link       (format "bookmark%s:%s" (if other-win "-other-win" "") bmk))
+               (bmk-desc   (format "Bookmark: %s" bmk)))
+          (org-store-link-props :type "bookmark" :link link :description bmk-desc))))
+
+  (advice-add 'org-store-link :before #'bmkp-reset-bmkp-store-org-link-checking-p)
+  (defun bmkp-reset-bmkp-store-org-link-checking-p (&rest _IGNORE)
+    "Reset `bmkp-store-org-link-checking-p' to nil."
+    (setq bmkp-store-org-link-checking-p  nil)))
+
+(defun bmkp-ffap-guesser ()
+  "`ffap-guesser', but deactivate a large active region first."
+  (and (require 'ffap nil t)
+       ;; Prevent using a large active region to guess ffap: Emacs bug #25243.
+       (let ((mark-active  (and mark-active  (< (buffer-size) bmkp-ffap-max-region-size))))
+         (ffap-guesser))))
+
+;; Same as `icicle-thing-at-point'.
+(defun bmkp-thing-at-point (thing &optional syntax-table)
+  "`thingatpt+.el' version of `thing-at-point', if possible.
+`tap-thing-at-point' if defined, else `thing-at-point'.
+if non-nil, set SYNTAX-TABLE for the duration."
+  (if (fboundp 'tap-thing-at-point)
+      (tap-thing-at-point thing syntax-table)
+    (if (and (syntax-table-p syntax-table)  (fboundp 'with-syntax-table)) ; Emacs 21+.
+        (with-syntax-table syntax-table (thing-at-point thing))
+      (thing-at-point thing))))         ; Ignore any SYNTAX-TABLE arg for Emacs 20, for vanilla.
+
+(defun bmkp-get-external-annotation (annotation)
+  "Return a cons (DESTINATION . TYPE) for ANNOTATION.
+DESTINATION is a string naming a file, a URL, or a bookmark.
+TYPE is `FILE', `URL', or `BOOKMARK', accordingly."
+  (cond ((string-match "\\`\\s-*bmkp-annot-file:\\s-*\"\\(\.+\\)\"" annotation)
+         (cons (match-string 1 annotation) 'FILE))
+        ((string-match "\\`\\s-*bmkp-annot-url:\\s-*\"\\(\.+\\)\"" annotation)
+         (cons (match-string 1 annotation) 'URL))
+        ((string-match "\\`\\s-*bmkp-annot-bmk:\\s-*\"\\(\.+\\)\"" annotation)
+         (cons (match-string 1 annotation) 'BOOKMARK))
+        (t nil)))
+
+(defun bmkp-visit-external-annotation (annotation.type msg-p)
+  "Visit the external annotation represented by ANNOTATION.TYPE.
+The first arg is a cons as returned by `bmkp-get-external-annotation'.
+I MSG-P is non-nil then echo the annotation type."
+  (let ((ann   (car annotation.type))
+        (type  (cdr annotation.type)))
+    (case type
+      (FILE       (find-file-other-window     ann))
+      (URL        (browse-url                 ann))
+      (BOOKMARK   (bookmark-jump-other-window ann))
+      (otherwise  (error "`bmkp-visit-external-annotation': Bad annotation type: `%S'" type)))
+    (message "Showing external annotation of type %s" type) (sit-for 1)))
+
+;;;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'bookmark+-1)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; bookmark+-1.el ends here
diff --git a/lisp/bookmark+-bmu.el b/lisp/bookmark+-bmu.el
new file mode 100644 (file)
index 0000000..9fe5a12
--- /dev/null
@@ -0,0 +1,6777 @@
+;;; bookmark+-bmu.el --- Bookmark+ code for the `*Bookmark List*' (bmenu).
+;;
+;; Filename: bookmark+-bmu.el
+;; Description: Bookmark+ code for the `*Bookmark List*' (bmenu).
+;; Author: Drew Adams, Thierry Volpiatto
+;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com")
+;; Copyright (C) 2000-2022, Drew Adams, all rights reserved.
+;; Copyright (C) 2009, Thierry Volpiatto, all rights reserved.
+;; Created: Mon Jul 12 09:05:21 2010 (-0700)
+;; Last-Updated: Fri Jan 14 12:40:58 2022 (-0800)
+;;           By: dradams
+;;     Update #: 4177
+;; URL: https://www.emacswiki.org/emacs/download/bookmark%2b-bmu.el
+;; Doc URL: https://www.emacswiki.org/emacs/BookmarkPlus
+;; Keywords: bookmarks, bookmark+, placeholders, annotations, search, info, url, eww, w3m, gnus
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x, 24.x, 25.x, 26.x
+;;
+;; Features that might be required by this library:
+;;
+;;   `apropos', `apropos+', `avoid', `backquote', `bookmark',
+;;   `bookmark+', `bookmark+-1', `bookmark+-bmu', `bookmark+-key',
+;;   `bookmark+-lit', `button', `bytecomp', `cconv', `cl', `cl-lib',
+;;   `cmds-menu', `col-highlight', `crosshairs', `fit-frame',
+;;   `font-lock', `font-lock+', `frame-fns', `gv', `help+',
+;;   `help-fns', `help-fns+', `help-macro', `help-macro+',
+;;   `help-mode', `hl-line', `hl-line+', `info', `info+', `kmacro',
+;;   `macroexp', `menu-bar', `menu-bar+', `misc-cmds', `misc-fns',
+;;   `naked', `pp', `pp+', `radix-tree', `rect', `replace',
+;;   `second-sel', `strings', `syntax', `text-mode', `thingatpt',
+;;   `thingatpt+', `vline', `w32browser-dlgopen', `wid-edit',
+;;   `wid-edit+'.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;    This library contains code for buffer `*Bookmark List*' (mode
+;;    `bookmark-bmenu-mode').
+;;
+;;    The Bookmark+ libraries are these:
+;;
+;;    `bookmark+.el'     - main (driver) library
+;;    `bookmark+-mac.el' - Lisp macros
+;;    `bookmark+-lit.el' - (optional) code for highlighting bookmarks
+;;    `bookmark+-bmu.el' - code for the `*Bookmark List*' (this file)
+;;    `bookmark+-1.el'   - other required code (non-bmenu)
+;;    `bookmark+-key.el' - key and menu bindings
+;;
+;;    `bookmark+-doc.el' - documentation (comment-only file)
+;;    `bookmark+-chg.el' - change log (comment-only file)
+;;
+;;    The documentation (in `bookmark+-doc.el') includes how to
+;;    byte-compile and install Bookmark+.  The documentation is also
+;;    available in these ways:
+;;
+;;    1. From the bookmark list (`C-x r l'):
+;;       Use `?' to show the current bookmark-list status and general
+;;       help, then click link `Doc in Commentary' or link `Doc on the
+;;       Web'.
+;;
+;;    2. From the Emacs-Wiki Web site:
+;;       https://www.emacswiki.org/emacs/BookmarkPlus.
+;;
+;;    3. From the Bookmark+ group customization buffer:
+;;       `M-x customize-group bookmark-plus', then click link
+;;       `Commentary'.
+;;
+;;    (The commentary links in #1 and #3 work only if you have library
+;;    `bookmark+-doc.el' in your `load-path'.)
+ 
+;;(@> "Index")
+;;
+;;  Index
+;;  -----
+;;
+;;  If you have library `linkd.el' and Emacs 22 or later, load
+;;  `linkd.el' and turn on `linkd-mode' now.  It lets you easily
+;;  navigate around the sections of this doc.  Linkd mode will
+;;  highlight this Index, as well as the cross-references and section
+;;  headings throughout this file.  You can get `linkd.el' here:
+;;  https://www.emacswiki.org/emacs/download/linkd.el.
+;;
+;;  (@> "Things Defined Here")
+;;  (@> "Utility Functions")
+;;  (@> "Faces (Customizable)")
+;;  (@> "User Options (Customizable)")
+;;  (@> "Internal Variables")
+;;  (@> "Compatibility Code for Older Emacs Versions")
+;;  (@> "Menu List Replacements (`bookmark-bmenu-*')")
+;;  (@> "Bookmark+ Functions (`bmkp-*')")
+;;    (@> "Menu-List (`*-bmenu-*') Filter Commands")
+;;    (@> "Menu-List (`*-bmenu-*') Commands Involving Marks")
+;;    (@> "Omitted Bookmarks")
+;;    (@> "Search-and-Replace Locations of Marked Bookmarks")
+;;    (@> "Tags")
+;;    (@> "General Menu-List (`-*bmenu-*') Commands and Functions")
+;;    (@> "Sorting - Commands")
+;;    (@> "Other Bookmark+ Functions (`bmkp-*')")
+;;  (@> "Keymaps")
+ 
+;;(@* "Things Defined Here")
+;;
+;;  Things Defined Here
+;;  -------------------
+;;
+;;  Commands defined here:
+;;
+;;    `bmkp-bmenu-add-tags', `bmkp-bmenu-add-tags-to-marked',
+;;    `bmkp-bmenu-change-sort-order',
+;;    `bmkp-bmenu-change-sort-order-repeat',
+;;    `bmkp-bmenu-clone-bookmark', `bmkp-bmenu-copy-bookmark',
+;;    `bmkp-bmenu-copy-marked-to-bookmark-file',
+;;    `bmkp-bmenu-copy-tags',
+;;    `bmkp-bmenu-create-bookmark-file-from-marked',
+;;    `bmkp-bmenu-define-command',
+;;    `bmkp-bmenu-define-full-snapshot-command',
+;;    `bmkp-bmenu-define-jump-marked-command',
+;;    `bmkp-bmenu-delete-marked', `bmkp-bmenu-describe-marked',
+;;    `bmkp-bmenu-describe-this+move-down',
+;;    `bmkp-bmenu-describe-this+move-up',
+;;    `bmkp-bmenu-describe-this-bookmark',`bmkp-bmenu-dired-marked',
+;;    `bmkp-bmenu-edit-annotations-for-marked',
+;;    `bmkp-bmenu-edit-bookmark-name-and-location',
+;;    `bmkp-bmenu-filter-annotation-incrementally',
+;;    `bmkp-bmenu-filter-bookmark-name-incrementally',
+;;    `bmkp-bmenu-filter-file-name-incrementally',
+;;    `bmkp-bmenu-filter-tags-incrementally',
+;;    `bmkp-bmenu-flag-for-deletion',
+;;    `bmkp-bmenu-flag-for-deletion-backwards',
+;;    `bmkp-bmenu-isearch-marked-bookmarks' (Emacs 23+),
+;;    `bmkp-bmenu-isearch-marked-bookmarks-regexp' (Emacs 23+),
+;;    `bmkp-bmenu-jump-to-marked', `bmkp-bmenu-load-marking',
+;;    `bmkp-bmenu-load-marking-unmark-first',
+;;    `bmkp-bmenu-make-sequence-from-marked', `bmkp-bmenu-mark-all',
+;;    `bmkp-bmenu-mark-autofile-bookmarks',
+;;    `bmkp-bmenu-mark-bookmark-file-bookmarks',
+;;    `bmkp-bmenu-mark-bookmark-list-bookmarks',
+;;    `bmkp-bmenu-mark-bookmarks-satisfying',
+;;    `bmkp-bmenu-mark-bookmarks-tagged-all',
+;;    `bmkp-bmenu-mark-bookmarks-tagged-none',
+;;    `bmkp-bmenu-mark-bookmarks-tagged-not-all',
+;;    `bmkp-bmenu-mark-bookmarks-tagged-regexp',
+;;    `bmkp-bmenu-mark-bookmarks-tagged-some',
+;;    `bmkp-bmenu-mark-desktop-bookmarks',
+;;    `bmkp-bmenu-mark-dired-bookmarks',
+;;    `bmkp-bmenu-mark-eww-bookmarks' (Emacs 25+),
+;;    `bmkp-bmenu-mark-file-bookmarks',
+;;    `bmkp-bmenu-mark-function-bookmarks',
+;;    `bmkp-bmenu-mark-gnus-bookmarks',
+;;    `bmkp-bmenu-mark-icicles-search-hits-bookmarks',
+;;    `bmkp-bmenu-mark-image-bookmarks',
+;;    `bmkp-bmenu-mark-info-bookmarks',
+;;    `bmkp-bmenu-mark-lighted-bookmarks',
+;;    `bmkp-bmenu-mark-man-bookmarks',
+;;    `bmkp-bmenu-mark-non-file-bookmarks',
+;;    `bmkp-bmenu-mark-non-invokable-bookmarks',
+;;    `bmkp-bmenu-mark-orphaned-local-file-bookmarks',
+;;    `bmkp-bmenu-mark-region-bookmarks',
+;;    `bmkp-bmenu-mark-snippet-bookmarks',
+;;    `bmkp-bmenu-mark-specific-buffer-bookmarks',
+;;    `bmkp-bmenu-mark-specific-file-bookmarks',
+;;    `bmkp-bmenu-mark-url-bookmarks',
+;;    `bmkp-bmenu-mark-variable-list-bookmarks',
+;;    `bmkp-bmenu-mark-w3m-bookmarks', `bmkp-bmenu-mouse-3-menu',
+;;    `bmkp-bmenu-mode-status-help',
+;;    `bmkp-bmenu-move-marked-to-bookmark-file',
+;;    `bmkp-bmenu-nb-marked-in-mode-name', `bmkp-bmenu-omit',
+;;    `bmkp-bmenu-omit-marked', `bmkp-bmenu-omit/unomit-marked',
+;;    `bmkp-bmenu-paste-add-tags',
+;;    `bmkp-bmenu-paste-add-tags-to-marked',
+;;    `bmkp-bmenu-paste-replace-tags',
+;;    `bmkp-bmenu-paste-replace-tags-for-marked',
+;;    `bmkp-bmenu-query-replace-marked-bookmarks-regexp',
+;;    `bmkp-bmenu-quit', `bmkp-bmenu-refresh-menu-list',
+;;    `bmkp-bmenu-regexp-mark', `bookmark-bmenu-relocate' (Emacs 20,
+;;    21), `bmkp-bmenu-relocate-marked', `bmkp-bmenu-remove-all-tags',
+;;    `bmkp-bmenu-remove-tags', `bmkp-bmenu-remove-tags-from-marked',
+;;    `bmkp-bmenu-search-marked-bookmarks-regexp',
+;;    `bmkp-bmenu-set-bookmark-file-bookmark-from-marked',
+;;    `bmkp-bmenu-set-tag-value',
+;;    `bmkp-bmenu-set-tag-value-for-marked', `bmkp-bmenu-show-all',
+;;    `bmkp-bmenu-show-only-autofile-bookmarks',
+;;    `bmkp-bmenu-show-only-autonamed-bookmarks',
+;;    `bmkp-bmenu-show-only-bookmark-file-bookmarks',
+;;    `bmkp-bmenu-show-only-bookmark-list-bookmarks',
+;;    `bmkp-bmenu-show-only-desktop-bookmarks',
+;;    `bmkp-bmenu-show-only-dired-bookmarks',
+;;    `bmkp-bmenu-show-only-eww-bookmarks' (Emacs 25+),
+;;    `bmkp-bmenu-show-only-file-bookmarks',
+;;    `bmkp-bmenu-show-only-function-bookmarks',
+;;    `bmkp-bmenu-show-only-gnus-bookmarks',
+;;    `bmkp-bmenu-show-only-icicles-search-hits-bookmarks.',
+;;    `bmkp-bmenu-show-only-image-bookmarks',
+;;    `bmkp-bmenu-show-only-info-bookmarks',
+;;    `bmkp-bmenu-show-only-man-bookmarks',
+;;    `bmkp-bmenu-show-only-non-file-bookmarks',
+;;    `bmkp-bmenu-show-only-non-invokable-bookmarks',
+;;    `bmkp-bmenu-show-only-omitted-bookmarks',
+;;    `bmkp-bmenu-show-only-orphaned-local-file-bookmarks',
+;;    `bmkp-bmenu-show-only-region-bookmarks',
+;;    `bmkp-bmenu-show-only-snippet-bookmarks',
+;;    `bmkp-bmenu-show-only-specific-buffer-bookmarks',
+;;    `bmkp-bmenu-show-only-specific-file-bookmarks',
+;;    `bmkp-bmenu-show-only-temporary-bookmarks',
+;;    `bmkp-bmenu-show-only-tagged-bookmarks',
+;;    `bmkp-bmenu-show-only-untagged-bookmarks',
+;;    `bmkp-bmenu-show-only-url-bookmarks',
+;;    `bmkp-bmenu-show-only-variable-list-bookmarks',
+;;    `bmkp-bmenu-show-only-w3m-bookmarks',
+;;    `bmkp-bmenu-show-or-edit-annotation',
+;;    `bmkp-bmenu-show-this-annotation+move-down',
+;;    `bmkp-bmenu-show-this-annotation+move-up',
+;;    `bmkp-bmenu-sort-annotated-before-unannotated',
+;;    `bmkp-bmenu-sort-by-bookmark-name',
+;;    `bmkp-bmenu-sort-by-bookmark-visit-frequency',
+;;    `bmkp-bmenu-sort-by-bookmark-type',
+;;    `bmkp-bmenu-sort-by-creation-time',
+;;    `bmkp-bmenu-sort-by-file-name',
+;;    `bmkp-bmenu-sort-by-Gnus-thread',
+;;    `bmkp-bmenu-sort-by-Info-node-name',
+;;    `bmkp-bmenu-sort-by-Info-position',
+;;    `bmkp-bmenu-sort-by-last-bookmark-access',
+;;    `bmkp-bmenu-sort-by-last-buffer-or-file-access',
+;;    `bmkp-bmenu-sort-by-last-local-file-access',
+;;    `bmkp-bmenu-sort-by-last-local-file-update',
+;;    `bmkp-bmenu-sort-by-local-file-size',
+;;    `bmkp-bmenu-sort-by-local-file-type', `bmkp-bmenu-sort-by-url',
+;;    `bmkp-bmenu-sort-flagged-before-unflagged',
+;;    `bmkp-bmenu-sort-marked-before-unmarked',
+;;    `bmkp-bmenu-sort-modified-before-unmodified',
+;;    `bmkp-bmenu-sort-tagged-before-untagged',
+;;    `bmkp-bmenu-toggle-marked-temporary/savable',
+;;    `bmkp-bmenu-toggle-marks', `bmkp-bmenu-toggle-show-only-marked',
+;;    `bmkp-bmenu-toggle-show-only-unmarked',
+;;    `bmkp-bmenu-toggle-temporary', `bmkp-bmenu-unmark-all',
+;;    `bmkp-bmenu-unmark-bookmarks-tagged-all',
+;;    `bmkp-bmenu-unmark-bookmarks-tagged-none',
+;;    `bmkp-bmenu-unmark-bookmarks-tagged-not-all',
+;;    `bmkp-bmenu-unmark-bookmarks-tagged-regexp',
+;;    `bmkp-bmenu-unmark-bookmarks-tagged-some',
+;;    `bmkp-bmenu-unomit-marked', `bmkp-bmenu-w32-open',
+;;    `bmkp-bmenu-w32-open-select', `bmkp-bmenu-w32-open-with-mouse',
+;;    `bmkp-define-tags-sort-command'.
+;;
+;;  Faces defined here:
+;;
+;;    `bmkp-*-mark', `bmkp->-mark', `bmkp-a-mark',
+;;    `bmkp-bad-bookmark', `bmkp-bookmark-file', `bmkp-bookmark-list',
+;;    `bmkp-buffer', `bmkp-D-mark', `bmkp-desktop',
+;;    `bmkp-file-handler', `bmkp-function', `bmkp-gnus',
+;;    `bmkp-heading', `bmkp-info', `bmkp-local-directory',
+;;    `bmkp-local-file-with-region', `bmkp-local-file-without-region',
+;;    `bmkp-man', `bmkp-no-jump', `bmkp-no-local', `bmkp-non-file',
+;;    `bmkp-remote-file', `bmkp-sequence', `bmkp-snippet',
+;;    `bmkp-su-or-sudo', `bmkp-t-mark', `bmkp-url',
+;;    `bmkp-variable-list', `bmkp-X-mark'.
+;;
+;;  User options defined here:
+;;
+;;    `bmkp-bmenu-commands-file',
+;;    `bmkp-bmenu-image-bookmark-icon-file',
+;;    `bmkp-bmenu-omitted-bookmarks', `bmkp-bmenu-state-file',
+;;    `bmkp-propertize-bookmark-names-flag', `bmkp-sort-orders-alist',
+;;    `bmkp-sort-orders-for-cycling-alist'.
+;;
+;;  Non-interactive functions defined here:
+;;
+;;    `bmkp--pop-to-buffer-same-window', `bmkp-assoc-delete-all',
+;;    `bmkp-bmenu-barf-if-not-in-menu-list',
+;;    `bmkp-bmenu-cancel-incremental-filtering',
+;;    `bmkp-bmenu-filter-alist-by-annotation-regexp',
+;;    `bmkp-bmenu-filter-alist-by-bookmark-name-regexp',
+;;    `bmkp-bmenu-filter-alist-by-file-name-regexp',
+;;    `bmkp-bmenu-filter-alist-by-tags-regexp',
+;;    `bmkp-bmenu-get-marked-files', `bmkp-bmenu-goto-bookmark-named',
+;;    `bmkp-bmenu-kill-annotation', `bmkp-bmenu-list-1',
+;;    `bmkp-bmenu-mark/unmark-bookmarks-tagged-all/none',
+;;    `bmkp-bmenu-mark/unmark-bookmarks-tagged-some/not-all',
+;;    `bmkp-bmenu-mode-line', `bmkp-bmenu-mode-line-string',
+;;    `bmkp-bmenu-propertize-item', `bmkp-bmenu-read-filter-input',
+;;    `bmkp-bmenu-store-org-link' (Emacs 24.4+),
+;;    `bmkp-bookmark-data-from-record',
+;;    `bmkp-bookmark-name-from-record', `bmkp-face-prop',
+;;    `bmkp-bmenu-marked-or-this-or-all', `bmkp-looking-at-p',
+;;    `bmkp-maybe-unpropertize-bookmark-names',
+;;    `bmkp-maybe-unpropertize-string', `bmkp-remap',
+;;    `bmkp-replace-regexp-in-string',
+;;    `bmkp-reverse-multi-sort-order', `bmkp-reverse-sort-order',
+;;    `bmkp-string-match-p', `bookmark-name-from-full-record',
+;;    `bookmark-name-from-record',
+;;
+;;  Internal variables defined here:
+;;
+;;    `bmkp-bmenu-before-hide-marked-alist',
+;;    `bmkp-bmenu-before-hide-unmarked-alist',
+;;    `bmkp-bmenu-bookmark-file-menu',
+;;    `bmkp-bmenu-define-command-history',
+;;    `bmkp-bmenu-define-command-menu', `bmkp-bmenu-delete-menu',
+;;    `bmkp-bmenu-filter-function', `bmkp-bmenu-filter-pattern',
+;;    `bmkp-bmenu-filter-timer', `bmkp-bmenu-first-time-p',
+;;    `bmkp-bmenu-header-lines', `bmkp-bmenu-highlight-menu',
+;;    `bmkp-bmenu-line-overlay', `bmkp-bmenu-mark-menu',
+;;    `bmkp-bmenu-marked-bookmarks', `bmkp-bmenu-marks-width',
+;;    `bmkp-bmenu-mark-types-menu', `bmkp-bmenu-menubar-menu',
+;;    `bmkp-bmenu-omit-menu', `bmkp-bmenu-search-menu',
+;;    `bmkp-bmenu-show-menu',
+;;    `bmkp-bmenu-show-types-menu',`bmkp-bmenu-sort-menu',
+;;    `bmkp-bmenu-tags-menu', `bmkp-bmenu-title',
+;;    `bmkp-bmenu-toggle-menu', `bmkp-flagged-bookmarks',
+;;    `bmkp-last-bmenu-bookmark'.
+;;
+;;
+;;  ***** NOTE: The following commands defined in `bookmark.el'
+;;              have been REDEFINED HERE:
+;;
+;;    `bookmark-bmenu-execute-deletions', `bookmark-bmenu-list',
+;;    `bookmark-bmenu-mark', `bookmark-bmenu-1-window',
+;;    `bookmark-bmenu-2-window', `bookmark-bmenu-other-frame',
+;;    `bookmark-bmenu-other-window',
+;;    `bookmark-bmenu-other-window-with-mouse',
+;;    `bookmark-bmenu-rename', `bookmark-bmenu-show-annotation',
+;;    `bookmark-bmenu-switch-other-window',
+;;    `bookmark-bmenu-this-window', `bookmark-bmenu-toggle-filenames',
+;;    `bookmark-bmenu-unmark'.
+;;
+;;
+;;  ***** NOTE: The following non-interactive functions and macros
+;;              defined in `bookmark.el' have been REDEFINED HERE:
+;;
+;;    `bookmark-bmenu-bookmark', `bookmark-bmenu-check-position',
+;;    `bookmark-bmenu-delete', `bookmark-bmenu-delete-backwards',
+;;    `bookmark-bmenu-ensure-position' (Emacs 23.2+),
+;;    `bookmark-bmenu-hide-filenames', `bookmark-bmenu-mode',
+;;    `bookmark-bmenu-show-filenames',
+;;    `bookmark-bmenu-surreptitiously-rebuild-list',
+;;    `with-buffer-modified-unmodified' (Emacs < 23.2).
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 3, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;
+
+(eval-when-compile (require 'cl)) ;; case (plus, for Emacs 20: dolist, push)
+(eval-when-compile (require 'easymenu)) ;; easy-menu-create-menu
+(eval-when-compile (require 'org nil t)) ;; org-add-link-type
+
+(require 'bookmark)
+;; bookmark-alist, bookmark-bmenu-file-column,
+;; bookmark-bmenu-hidden-bookmarks, bookmark-bmenu-mode-map,
+;; bookmark-bmenu-select, bookmark-get-annotation,
+;; bookmark-get-filename, bookmark-get-handler, bookmark-kill-line,
+;; bookmark-maybe-load-default-file, bookmark-name-from-full-record,
+;; bookmark-name-from-record, bookmark-prop-get
+
+
+;; Some general Renamings.
+;;
+;; 1. Fix incompatibility introduced by gratuitous Emacs name change.
+;;
+(cond ((and (fboundp 'bookmark-name-from-record)  (not (fboundp 'bookmark-name-from-full-record)))
+       (defalias 'bookmark-name-from-full-record 'bookmark-name-from-record))
+      ((and (fboundp 'bookmark-name-from-full-record)  (not (fboundp 'bookmark-name-from-record)))
+       (defalias 'bookmark-name-from-record 'bookmark-name-from-full-record)))
+
+;; 2. The vanilla name of the first is misleading, as it returns only the cdr of the record.
+;;    The second is for consistency.
+;;
+(defalias 'bmkp-bookmark-data-from-record 'bookmark-get-bookmark-record)
+(defalias 'bmkp-bookmark-name-from-record 'bookmark-name-from-full-record)
+
+
+(eval-when-compile
+ (or (condition-case nil
+         (load-library "bookmark+-mac") ; Use load-library to ensure latest .elc.
+       (error nil))
+     (require 'bookmark+-mac)))         ; Require, so can load separately if not on `load-path'.
+;; bmkp-define-show-only-command, bmkp-define-sort-command, bmkp-menu-bar-make-toggle,
+;; bmkp-with-help-window, bmkp-with-output-to-plain-temp-buffer
+
+(put 'bmkp-with-output-to-plain-temp-buffer 'common-lisp-indent-function '(4 &body))
+
+
+;;; These functions are used in macro `bmkp-define-sort-command'.  The first is used in the macro code
+;;; that produces the function code, so its definition is also in `bookmark+-mac.el'.
+;;;
+(defun bmkp-replace-regexp-in-string (regexp rep string &optional fixedcase literal subexp start)
+  "Replace all matches for REGEXP with REP in STRING and return STRING."
+  (if (fboundp 'replace-regexp-in-string) ; Emacs > 20.
+      (replace-regexp-in-string regexp rep string fixedcase literal subexp start)
+    (if (string-match regexp string) (replace-match rep nil nil string) string))) ; Emacs 20
+
+(defun bmkp-assoc-delete-all (key alist)
+  "Delete from ALIST all elements whose car is `equal' to KEY.
+Return the modified alist.
+Elements of ALIST that are not conses are ignored."
+  (while (and (consp (car alist)) (equal (car (car alist)) key))  (setq alist  (cdr alist)))
+  (let ((tail  alist)
+        tail-cdr)
+    (while (setq tail-cdr  (cdr tail))
+      (if (and (consp (car tail-cdr))  (equal (car (car tail-cdr)) key))
+          (setcdr tail (cdr tail-cdr))
+        (setq tail  tail-cdr))))
+  alist)
+
+
+;; (eval-when-compile (require 'bookmark+-1))
+
+;; bmkp-add-tags, bmkp-alpha-p, bmkp-bookmark-creation-cp,
+;; bmkp-bookmark-description, bmkp-bookmark-file-bookmark-p,
+;; bmkp-bookmark-last-access-cp, bmkp-bookmark-list-bookmark-p,
+;; bmkp-buffer-last-access-cp, bmkp-completing-read-buffer-name,
+;; bmkp-completing-read-file-name, bmkp-current-bookmark-file,
+;; bmkp-current-sort-order, bmkp-describe-bookmark,
+;; bmkp-describe-bookmark-internals, bmkp-desktop-bookmark-p,
+;; bmkp-edit-bookmark-name-and-location, bmkp-file-alpha-cp,
+;; bmkp-file-remote-p, bmkp-function-bookmark-p, bmkp-get-bookmark,
+;; bmkp-get-buffer-name, bmkp-get-tags, bmkp-gnus-bookmark-p,
+;; bmkp-gnus-cp, bmkp-handler-cp, bmkp-incremental-filter-delay,
+;; bmkp-image-bookmark-p, bmkp-info-bookmark-p,
+;; bmkp-info-node-name-cp, bmkp-info-position-cp,
+;; bmkp-isearch-bookmarks, bmkp-isearch-bookmarks-regexp, bmkp-jump-1,
+;; bmkp-last-bookmark-file, bmkp-last-specific-buffer,
+;; bmkp-last-specific-file, bmkp-latest-bookmark-alist,
+;; bmkp-local-file-bookmark-p, bmkp-local-file-type-cp,
+;; bmkp-local-file-accessed-more-recently-cp,
+;; bmkp-local-file-updated-more-recently-cp,
+;; bmkp-set-sequence-bookmark, bmkp-man-bookmark-p,
+;; bmkp-marked-bookmark-p, bmkp-marked-bookmarks-only, bmkp-marked-cp,
+;; bmkp-msg-about-sort-order, bmkp-non-file-filename,
+;; bmkp-read-tag-completing, bmkp-read-tags-completing,
+;; bmkp-refresh-menu-list, bmkp-region-bookmark-p,
+;; bmkp-remove-all-tags, bmkp-remove-if, bmkp-remove-tags,
+;; bmkp-repeat-command, bmkp-reverse-multi-sort-p,
+;; bmkp-reverse-sort-p, bmkp-root-or-sudo-logged-p, bmkp-same-file-p,
+;; bmkp-save-menu-list-state, bmkp-sequence-bookmark-p,
+;; bmkp-set-tag-value, bmkp-set-tag-value-for-bookmarks,
+;; bmkp-set-union, bmkp-snippet-alist-only, bmkp-snippet-bookmark-p,
+;; bmkp-some, bmkp-some-marked-p, bmkp-some-unmarked-p,
+;; bmkp-sort-omit, bmkp-sort-comparer, bmkp-sorted-alist,
+;; bmkp-su-or-sudo-regexp, bmkp-tag-name, bmkp-tags-list,
+;; bmkp-url-bookmark-p, bmkp-url-cp, bmkp-unmarked-bookmarks-only,
+;; bmkp-variable-list-bookmark-p, bmkp-visited-more-cp
+
+;; (eval-when-compile (require 'bookmark+-lit nil t))
+;; bmkp-get-lighting
+
+;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Quiet the byte-compiler
+(defvar bookmark-file-coding-system)    ; In `bookmark.el' (Emacs 25.2+)
+(defvar bmkp-bmenu-buffer)              ; In `bookmark+.el'
+(defvar bmkp-bmenu-highlight-menu)      ; Defined in this file (conditionally).
+(defvar bmkp-copied-tags)               ; In `bookmark+-1.el'.
+(defvar bmkp-count-multi-mods-as-one-flag) ; In `bookmark+-1.el'.
+(defvar bmkp-current-bookmark-file)     ; In `bookmark+-1.el'.
+(defvar bmkp-edit-bookmark-orig-record) ; In `bookmark+-1.el'.
+(defvar bmkp-incremental-filter-delay)  ; In `bookmark+-1.el'.
+(defvar bmkp-edit-bookmark-records-number) ; In `bookmark+-1.el'.
+(defvar bmkp-last-bookmark-file)        ; In `bookmark+-1.el'.
+(defvar bmkp-last-specific-buffer)      ; In `bookmark+-1.el'.
+(defvar bmkp-last-specific-file)        ; In `bookmark+-1.el'.
+(defvar bmkp-latest-bookmark-alist)     ; In `bookmark+-1.el'.
+(defvar bmkp-modified-bookmarks)        ; In `bookmark+-1.el'.
+(defvar bmkp-non-file-filename)         ; In `bookmark+-1.el'.
+(defvar bmkp-reverse-multi-sort-p)      ; In `bookmark+-1.el'.
+(defvar bmkp-reverse-sort-p)            ; In `bookmark+-1.el'.
+(defvar bmkp-sort-comparer)             ; In `bookmark+-1.el'.
+(defvar bmkp-sorted-alist)              ; In `bookmark+-1.el'.
+(defvar bmkp-sort-orders-alist)         ; Here.
+(defvar bmkp-su-or-sudo-regexp)         ; In `bookmark+-1.el'.
+(defvar bmkp-temporary-bookmarking-mode) ; In `bookmark+-1.el'.
+(defvar dired-re-mark)                  ; In `dired.el'.
+(defvar icicle-candidate-properties-alist) ; In `icicles-var.el'.
+(defvar minibuffer-prompt-properties)   ; Emacs 22+.
+(defvar tramp-file-name-regexp)         ; In `tramp.el'.
+
+ 
+;;(@* "Utility Functions")
+;;; Utility Functions ------------------------------------------------
+
+;; Same as `tap-string-match-p' in `thingatpt+.el' and `icicle-string-match-p' in `icicles-fn.el'.
+(if (fboundp 'string-match-p)
+    (defalias 'bmkp-string-match-p 'string-match-p) ; Emacs 23+
+  (defun bmkp-string-match-p (regexp string &optional start)
+    "Like `string-match', but this saves and restores the match data."
+    (save-match-data (string-match regexp string start))))
+
+;; Same as `tap-looking-at-p' in `thingatpt+.el' and `icicle-looking-at-p' in `icicles-mcmd.el'.
+;; Do not `defalias' to Emacs `looking-at-p' because that is a `defsubst'.
+(defun bmkp-looking-at-p (regexp)
+  "Like `looking-at', but this saves and restores the match data."
+  (save-match-data (looking-at regexp)))
+
+;; Same as `icicle-remap' in `icicles-opt.el'.  Not used yet.
+(defun bmkp-remap (old new map &optional oldmap)
+  "Bind command NEW in MAP to all keys currently bound to OLD.
+If command remapping is available, use that.  Otherwise, bind NEW to
+whatever OLD is bound to in MAP, or in OLDMAP, if provided."
+  (if (fboundp 'command-remapping)
+      (define-key map (vector 'remap old) new) ; Ignore OLDMAP for Emacs 22.
+    (substitute-key-definition old new map oldmap)))
+
+;; This is also in `bookmark+-lit.el', since it is loaded first but is optional.
+;;
+(if (fboundp 'pop-to-buffer-same-window)
+    (defalias 'bmkp--pop-to-buffer-same-window 'pop-to-buffer-same-window)
+  (defalias 'bmkp--pop-to-buffer-same-window 'switch-to-buffer))
+ 
+;;(@* "Faces (Customizable)")
+;;; Faces (Customizable) ---------------------------------------------
+
+(defface bmkp->-mark '((((background dark)) (:foreground "Yellow"))
+                       (t (:foreground "Blue")))
+  ;; (:foreground "Magenta2" :box (:line-width 1 :style pressed-button))))
+  "*Face used for a `>' mark in the bookmark list."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-a-mark '((((background dark)) (:background "SaddleBrown"))
+                       (t (:background "SkyBlue")))
+  "*Face used for an annotation indicator (`a') in the bookmark list."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-bad-bookmark '((t (:foreground "Red" :background "Chartreuse1")))
+  "*Face used for a bookmark that seems to be bad: e.g., nonexistent file."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-bookmark-file
+    '((((background dark))
+       (:foreground "#00005A5AFFFF" :background "#FFFF9B9BFFFF")) ; ~ blue, ~ pink
+      (t (:foreground "Orange" :background "DarkGreen")))
+  "*Face used for a bookmark-file bookmark."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-bookmark-list
+    '((((background dark)) (:foreground "#7474FFFFFFFF" :background "DimGray")) ; ~ cyan
+      (t (:foreground "DarkRed" :background "LightGray")))
+  "*Face used for a bookmark-list bookmark."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-buffer
+    '((((background dark)) (:foreground "#FFFF9B9BFFFF")) ; ~ pink
+      (t (:foreground "DarkGreen")))
+  "*Face used for a bookmarked existing buffer not associated with a file."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-D-mark '((t (:foreground "Yellow" :background "Red")))
+  "*Face used for a deletion mark (`D') in the bookmark list."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-desktop
+    '((((background dark)) (:foreground "Orange" :background "DarkSlateBlue"))
+      (t (:foreground "DarkBlue" :background "PaleGoldenrod")))
+  "*Face used for a bookmarked desktop."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-file-handler
+    '((((background dark)) (:background "#FFFF78CB48E1")) ; ~ dark brown
+      (t (:background "LightBlue")))
+  "*Face used for a bookmark that has a `file-handler' attribute."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-function
+    '((((background dark)) (:foreground "#0000EBEB6C6C")) ; ~ green
+      (t (:foreground "DeepPink1")))
+  "*Face used for a function bookmark: a bookmark that invokes a function."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-gnus
+    '((((background dark)) (:foreground "Gold"))
+      (t (:foreground "DarkBlue")))
+  "*Face used for a Gnus bookmark."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-info
+    '((((background dark)) (:foreground "#7474FFFFFFFF")) ; ~ light cyan
+      (t (:foreground "DarkRed")))
+  "*Face used for a bookmarked Info node."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-local-directory
+    '((((background dark))
+       (:foreground "Pink" :background "DarkBlue"))
+      (t (:foreground "DarkBlue" :background "HoneyDew2")))
+  "*Face used for a bookmarked local directory."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-local-file-without-region
+    '((((background dark)) (:foreground "White"))
+      (t (:foreground "Black")))
+  "*Face used for a bookmarked local file (without a region)."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-local-file-with-region
+    '((((background dark)) (:foreground "Yellow"))
+      (t (:foreground "Blue")))
+  "*Face used for a region bookmark in a local file."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-man
+    '((((background dark)) (:foreground "Orchid"))
+      (t (:foreground "Orange4")))
+  "*Face used for a `man' page bookmark."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-*-mark '((t (:foreground "Red" :background "Yellow")))
+  "*Face used for a modification mark (`*') in the bookmark list."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-no-jump
+    '((t (:foreground "gray50")))
+  "*Face used for a bookmark you cannot jump to from `*Bookmark List*'."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-no-local
+    '((t (:background "orange")))
+  "*Face used for a local file bookmark whose target file does not exist."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-non-file
+    '((t (:foreground "MediumSeaGreen")))
+  "*Face used for a bookmark not associated with an existing buffer."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-remote-file
+    '((((background dark)) (:foreground "#6B6BFFFF2C2C")) ; ~ green
+      (t (:foreground "DarkViolet")))
+  "*Face used for a bookmarked tramp remote file (/ssh:)."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-sequence
+    '((((background dark)) (:foreground "DeepSkyBlue"))
+      (t (:foreground "DarkOrange2")))
+  "*Face used for a sequence bookmark: one composed of other bookmarks."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-snippet
+    (if (> emacs-major-version 21)
+        '((t (:inherit region)))
+      '((t (:background "MediumAquamarine"))))
+  "*Face used for a bookmarked snippet."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-su-or-sudo '((t (:foreground "Red")))
+  "*Face used for a bookmarked tramp file (/su: or /sudo:)."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-t-mark '((((background dark)) (:foreground "Magenta"))
+                       (t (:foreground "#000093F402A2"))) ; a medium green
+  "*Face used for a tags mark (`t') in the bookmark list."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-url
+    '((((background dark)) (:foreground "#7474FFFF7474")) ; ~ green
+      (t (:foreground "DarkMagenta")))
+  "*Face used for a bookmarked URL."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-variable-list
+    '((((background dark)) (:foreground "#FFFF8D947477")) ; ~ salmon
+      (t (:foreground "#0000726B8B8B")))     ; ~dark cyan
+  "*Face used for a bookmarked list of variables."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-X-mark '((t (:foreground "Red")))
+  "*Face used for a temporary-bookmark indicator (`X') in the bookmark list."
+  :group 'bookmark-plus :group 'faces)
+
+;; $$$$$$ Not used now - using `bmkp-url' instead.
+;; (defface bmkp-w3m
+;;     '((((background dark)) (:foreground "yellow"))
+;;       (t (:foreground "DarkMagenta")))
+;;   "*Face used for a bookmarked w3m url."
+;;   :group 'bookmark-plus :group 'faces)
+
+;; Instead of vanilla `bookmark-menu-heading' (defined in Emacs 22+), to use a better default.
+(defface bmkp-heading '((((background dark)) (:foreground "Yellow"))
+                        (t (:foreground "Blue")))
+  "*Face used to highlight the headings in various Bookmark+ buffers."
+  :group 'bookmark-plus :version "22.1" :group 'faces)
+ 
+;;(@* "User Options (Customizable)")
+;;; User Options (Customizable) --------------------------------------
+
+;;;###autoload (autoload 'bmkp-bmenu-omitted-bookmarks "bookmark+")
+(defcustom bmkp-bmenu-omitted-bookmarks ()
+  "*List of names of omitted bookmarks.
+They are generally not available for display in the bookmark list.
+You can, however, use \\<bookmark-bmenu-mode-map>\
+`\\[bmkp-bmenu-show-only-omitted-bookmarks]' to see them.
+You can then mark some of them and use `\\[bmkp-bmenu-omit/unomit-marked]'
+ to make those that are marked available again for the bookmark list."
+  ;; $$$$$$ TODO: Create a customize :type `bookmark-name'
+  ;;              and provide completion for filling out the field.
+  :type '(repeat (string :tag "Bookmark name")) :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-bmenu-commands-file "bookmark+")
+(defcustom bmkp-bmenu-commands-file (convert-standard-filename "~/.emacs-bmk-bmenu-commands.el")
+  "*File for saving user-defined bookmark-list commands.
+This must be an absolute file name (possibly containing `~') or nil
+\(it is not expanded).
+
+You can use `\\[bmkp-list-defuns-in-commands-file]' to list the
+commands defined in the file and how many times each is defined.
+
+NOTE: Each time you define a command using \\<bookmark-bmenu-mode-map>\
+`\\[bmkp-bmenu-define-command]', `\\[bmkp-bmenu-define-full-snapshot-command]', \
+`\\[bmkp-bmenu-define-jump-marked-command], or `\\[bmkp-define-tags-sort-command]',
+it is saved in the file.  The new definition is simply appended to the
+file - old definitions of the same command are not overwritten.  So
+you might want to clean up the file occasionally, to remove any old,
+unused definitions.  This is especially advisable if you used \
+`\\[bmkp-bmenu-define-full-snapshot-command]',
+because such command definitions can be very large."
+  :type '(file  :tag "File for saving menu-list state") :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-bmenu-state-file "bookmark+")
+(defcustom bmkp-bmenu-state-file (convert-standard-filename "~/.emacs-bmk-bmenu-state.el")
+  "*File for saving `*Bookmark List*' state when you quit bookmark list.
+This must be an absolute file name (possibly containing `~') or nil
+\(it is not expanded).
+
+The state is also saved when you quit Emacs, even if you don't quit
+the bookmark list first (using \\<bookmark-bmenu-mode-map>`\\[bmkp-bmenu-quit]').
+
+Set this to nil if you do not want to restore the bookmark list as it
+was the last time you used it."
+  :type '(choice
+          (const :tag "Do not save and restore menu-list state" nil)
+          (file  :tag "File for saving menu-list state"))
+  :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-bmenu-image-bookmark-icon-file "bookmark+")
+(defcustom bmkp-bmenu-image-bookmark-icon-file
+  (and (fboundp 'display-images-p)  (display-images-p)
+       (let ((bmk-img    (convert-standard-filename "~/.emacs-bmk-bmenu-image-file-icon.png"))
+             (emacs-img  (convert-standard-filename (concat data-directory "images/gnus/exit-gnus.xpm"))))
+         (or (and (file-readable-p bmk-img)    bmk-img)
+             (and (file-readable-p emacs-img)  emacs-img))))
+  "*Iconic image file to show next to image-file bookmarks.
+If nil, show no image.  Otherwise, this is an absolute file name,
+possibly containing `~', (the value is not expanded).
+
+Use any image file that Emacs can display, but you probably want to
+use a small, iconic image - say 16x16 pixels.
+
+The default image, which you are sure to have in any Emacs version
+that supports images, is 24x24 pixels.  That wastes vertical space, so
+you probably want to use something smaller.
+
+If you don't have another image that you prefer, try this one (16x16):
+https://www.emacswiki.org/emacs/BookmarkPlusImageFileDefaultIcon"
+  :type '(choice
+          (file  :tag "Use iconic image file")
+          (const :tag "Show no image"))
+  :group 'bookmark-plus)
+
+;; This is a general option.  It is in this file because it is used mainly by the bmenu code.
+(when (> emacs-major-version 20)
+  (defcustom bmkp-sort-orders-alist ()
+    "*Alist of all available sort functions.
+This is a pseudo option - you probably do NOT want to customize this.
+Instead:
+
+ * To add a new sort function to this list, use macro
+   `bmkp-define-sort-command'.  It defines a new sort function
+   and automatically adds it to this list.
+
+ * To have fewer sort orders available for cycling by \\<bookmark-bmenu-mode-map>\
+`\\[bmkp-bmenu-change-sort-order-repeat]'...,
+   customize option `bmkp-sort-orders-for-cycling-alist'.
+
+Each alist element has the form (SORT-ORDER . COMPARER):
+
+ SORT-ORDER is a short string or symbol describing the sort order.
+ Examples: \"by last access time\", \"by bookmark name\".
+
+ COMPARER compares two bookmarks.  It must be acceptable as a value of
+ `bmkp-sort-comparer'."
+    :type '(alist
+            :key-type (choice :tag "Sort order" string symbol)
+            :value-type (choice
+                         (const    :tag "None (do not sort)" nil)
+                         (function :tag "Sorting Predicate")
+                         (list     :tag "Sorting Multi-Predicate"
+                          (repeat (function :tag "Component Predicate"))
+                          (choice
+                           (const    :tag "None" nil)
+                           (function :tag "Final Predicate")))))
+    :group 'bookmark-plus))
+
+(unless (> emacs-major-version 20)      ; Emacs 20: custom type `alist' doesn't exist.
+  (defcustom bmkp-sort-orders-alist ()
+    "*Alist of all available sort functions.
+This is a pseudo option - you probably do NOT want to customize this.
+Instead:
+
+ * To add a new sort function to this list, use macro
+   `bmkp-define-sort-command'.  It defines a new sort function
+   and automatically adds it to this list.
+
+ * To have fewer sort orders available for cycling by \\<bookmark-bmenu-mode-map>\
+`\\[bmkp-bmenu-change-sort-order-repeat]'...,
+   customize option `bmkp-sort-orders-for-cycling-alist'.
+
+Each alist element has the form (SORT-ORDER . COMPARER):
+
+ SORT-ORDER is a short string or symbol describing the sort order.
+ Examples: \"by last access time\", \"by bookmark name\".
+
+ COMPARER compares two bookmarks.  It must be acceptable as a value of
+ `bmkp-sort-comparer'."
+    :type '(repeat
+            (cons
+             (choice :tag "Sort order" string symbol)
+             (choice
+              (const    :tag "None (do not sort)" nil)
+              (function :tag "Sorting Predicate")
+              (list     :tag "Sorting Multi-Predicate"
+               (repeat (function :tag "Component Predicate"))
+               (choice
+                (const    :tag "None" nil)
+                (function :tag "Final Predicate"))))))
+    :group 'bookmark-plus))
+
+(defcustom bmkp-propertize-bookmark-names-flag (> emacs-major-version 20)
+  "*Non-nil means to propertize bookmark names to hold full bookmark data.
+This means that you can effectively have more than one bookmark with
+the same name.
+
+Emacs 20 users: If you need to use your bookmarks with Emacs 20 then
+set this to nil.  In particular, if your bookmark file was written
+with this as non-nil, then it contains propertized strings which are
+unreadable by Emacs 20.  To convert the file to be usable with Emacs
+20 you must, in Emacs 21 or later, set this to nil and then do `M-x
+bookmark-save'."
+  :type 'boolean :group 'bookmark-plus)
+ 
+;;(@* "Internal Variables")
+;;; Internal Variables -----------------------------------------------
+
+(defconst bmkp-bmenu-header-lines 5
+  "Number of lines used for the `*Bookmark List*' header.")
+
+(defconst bmkp-bmenu-marks-width 4
+  "Number of columns (chars) used for the `*Bookmark List*' marks columns.
+Bookmark names thus begin in this column number (since zero-based).")
+
+
+(defvar bmkp-bmenu-before-hide-marked-alist ()
+  "Copy of `bookmark-alist' made before hiding marked bookmarks.")
+
+(defvar bmkp-bmenu-before-hide-unmarked-alist ()
+  "Copy of `bookmark-alist' made before hiding unmarked bookmarks.")
+
+(defvar bmkp-bmenu-define-command-history ()
+  "History of names of commands you have defined for `*Bookmark List*'.")
+
+(defvar bmkp-bmenu-filter-function  nil "Latest filtering function for `*Bookmark List*' display.")
+
+(defvar bmkp-bmenu-filter-pattern "" "Regexp for incremental filtering.")
+
+(defvar bmkp-bmenu-filter-timer nil "Timer used for incremental filtering.")
+
+(defvar bmkp-bmenu-first-time-p t
+  "Non-nil means bookmark list has not yet been shown after quitting it.
+Quitting the list or the Emacs session resets this to t.
+The first time the list is displayed, it is set to nil.")
+
+(defvar bmkp-bmenu-marked-bookmarks ()
+  "Names of the marked bookmarks.
+This includes possibly omitted bookmarks, that is, bookmarks listed in
+`bmkp-bmenu-omitted-bookmarks'.")
+
+(defvar bmkp-bmenu-title "" "Latest title for `*Bookmark List*' display.")
+
+(defvar bmkp-flagged-bookmarks ()
+  "Alist of bookmarks that are flagged for deletion in `*Bookmark List*'.")
+
+;; This is a general variable.  It is in this file because it is used only in the bmenu code.
+(defvar bmkp-last-bmenu-bookmark nil "The name of the last bookmark current in the bookmark list.")
+ 
+;;(@* "Compatibility Code for Older Emacs Versions")
+;;; Compatibility Code for Older Emacs Versions ----------------------
+
+(when (or (< emacs-major-version 23)  (and (= emacs-major-version 23)  (= emacs-minor-version 1)))
+  (defmacro with-buffer-modified-unmodified (&rest body)
+    "Save and restore `buffer-modified-p' state around BODY."
+    (let ((was-modified  (make-symbol "was-modified")))
+      `(let ((,was-modified  (buffer-modified-p)))
+        (unwind-protect (progn ,@body)
+          (set-buffer-modified-p ,was-modified))))))
+
+(when (< emacs-major-version 22)
+  (defun bookmark-bmenu-relocate ()
+    "Change the file path of the bookmark on the current line,
+prompting with completion for the new path."
+    (interactive)
+    (let ((bmk        (bookmark-bmenu-bookmark))
+          (thispoint  (point)))
+      (when bmk (bookmark-relocate bmk))
+      (goto-char thispoint))))
+ 
+;;(@* "Menu List Replacements (`bookmark-bmenu-*')")
+;;; Menu List Replacements (`bookmark-bmenu-*') ----------------------
+
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Return t.  Value doesn't mean anything (didn't anyway), but must be non-nil for vanilla Emacs.
+;; 2. Do not count lines.  Just make sure we're on a bookmark line.
+;;
+(defalias 'bookmark-bmenu-check-position 'bookmark-bmenu-ensure-position)
+(defun bookmark-bmenu-ensure-position ()
+  "Move to the beginning of the nearest bookmark line."
+  (beginning-of-line)
+  (unless (bookmark-bmenu-bookmark)
+    (if (and (bolp)  (eobp))
+        (beginning-of-line 0)
+      (goto-char (point-min))
+      (forward-line bmkp-bmenu-header-lines)))
+  t)                                    ; Older vanilla bookmark code depends on non-nil value.
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Add bookmark to `bmkp-bmenu-marked-bookmarks'.  Delete it from `bmkp-flagged-bookmarks'.
+;; 2. Don't call `bookmark-bmenu-ensure-position' again at end.
+;; 3. Raise error if not in `*Bookmark List*'.
+;; 4. Narrower scope for `with-buffer-modified-unmodified' and `let'.
+;; 5. If current sort is `s >' (marked first or last), and it was unmarked before, then re-sort.
+;; 6. Added optional arg NO-RE-SORT-P to inhibit #5.
+;; 7. Added optional arg MSG-P.
+;; 8. Call `bmkp-bmenu-mode-line'.
+;;
+;;;###autoload (autoload 'bookmark-bmenu-mark "bookmark+")
+(defun bookmark-bmenu-mark (&optional no-re-sort-p msg-p) ; Bound to `m' in bookmark list
+  "Mark the bookmark on this line, using mark `>'.
+Add its name to `bmkp-bmenu-marked-bookmarks', after propertizing it
+with the full bookmark as `bmkp-full-record'.
+
+If the bookmark was unmarked before, and if the sort order is marked
+first or last (`s >'), then re-sort.
+
+Non-interactively:
+* Non-nil optional arg NO-RE-SORT-P inhibits re-sorting.
+* Non-nil optional arg MSG-P means display a status message."
+  (interactive (list nil 'MSG-P))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bookmark-bmenu-ensure-position)
+  (beginning-of-line)
+  (with-buffer-modified-unmodified
+      (let ((inhibit-read-only  t))
+        (delete-char 1) (insert ?>) (put-text-property (1- (point)) (point) 'face 'bmkp->-mark)))
+  (let* ((bname           (bookmark-bmenu-bookmark))
+         (bmk             (bmkp-bookmark-record-from-name bname))
+         (was-unmarked-p  nil))
+    ;; Put full bookmark on BNAME as property `bmkp-full-record'.
+    (put-text-property 0 (length bname) 'bmkp-full-record bmk bname)
+    ;; This is the same as `add-to-list' with `eq' (not available for Emacs 20-21).
+    (unless (memq bname bmkp-bmenu-marked-bookmarks)
+      (setq bmkp-bmenu-marked-bookmarks  (cons bname bmkp-bmenu-marked-bookmarks)
+            was-unmarked-p               t))
+    (setq bmkp-flagged-bookmarks  (delq bmk bmkp-flagged-bookmarks))
+    (unless no-re-sort-p
+      ;; If it was unmarked but now is marked, and if sort order is `s >', then re-sort.
+      (when (and was-unmarked-p  (equal bmkp-sort-comparer '((bmkp-marked-cp) bmkp-alpha-p)))
+        (let ((curr-bmk  (bookmark-bmenu-bookmark)))
+          (bookmark-bmenu-surreptitiously-rebuild-list (not msg-p))
+          (when curr-bmk (bmkp-bmenu-goto-bookmark-named curr-bmk))))))
+  (forward-line 1)
+  (when (fboundp 'bmkp-bmenu-mode-line) (bmkp-bmenu-mode-line)))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Remove bookmark from `bmkp-bmenu-marked-bookmarks' and `bmkp-flagged-bookmarks'.
+;; 2. Use `bmkp-delete-bookmark-name-from-list', not `delete'.
+;; 3. Don't call `bookmark-bmenu-ensure-position' again at end.
+;; 4. Raise error if not in `*Bookmark List*'.
+;; 5. Narrower scope for `with-buffer-modified-unmodified' and `let'.
+;; 6. If current sort is `s >' (marked first or last), and it was marked before, then re-sort.
+;; 7. Added optional arg NO-RE-SORT-P to inhibit #6.
+;; 8. Added optional arg MSG-P.
+;; 9. Call `bmkp-bmenu-mode-line'.
+;;
+;;;###autoload (autoload 'bookmark-bmenu-unmark "bookmark+")
+(defun bookmark-bmenu-unmark (&optional backup no-re-sort-p msg-p) ; Bound to `u' in bookmark list
+  "Unmark the bookmark on this line, then move down to the next.
+With a prefix argument, move up instead.
+
+If the bookmark was marked before, and if the sort order is marked
+first or last (`s >'), then re-sort.
+
+Non-interactively:
+* Non-nil optional arg BACKUP (prefix arg) means move up.
+* Non-nil optional arg NO-RE-SORT-P inhibits re-sorting.
+* Non-nil optional arg MSG-P means display a status message."
+  (interactive (list current-prefix-arg nil 'MSG-P))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bookmark-bmenu-ensure-position)
+  (beginning-of-line)
+  (with-buffer-modified-unmodified
+      (let ((inhibit-read-only  t))
+        (delete-char 1) (insert " ")))
+  (let ((was-marked-p  (memq (bookmark-bmenu-bookmark) bmkp-bmenu-marked-bookmarks)))
+    (setq bmkp-bmenu-marked-bookmarks  (bmkp-delete-bookmark-name-from-list
+                                        (bookmark-bmenu-bookmark) bmkp-bmenu-marked-bookmarks)
+          bmkp-flagged-bookmarks       (delq (bmkp-bookmark-record-from-name (bookmark-bmenu-bookmark))
+                                             bmkp-flagged-bookmarks))
+    (unless no-re-sort-p
+      ;; If it was marked but now is unmarked, and if sort order is `s >', then re-sort.
+      (when (and was-marked-p  (equal bmkp-sort-comparer '((bmkp-marked-cp) bmkp-alpha-p)))
+        (let ((curr-bmk  (bookmark-bmenu-bookmark)))
+          (bookmark-bmenu-surreptitiously-rebuild-list (not msg-p))
+          (when curr-bmk (bmkp-bmenu-goto-bookmark-named curr-bmk))))))
+  (forward-line (if backup -1 1))
+  (when (fboundp 'bmkp-bmenu-mode-line) (bmkp-bmenu-mode-line)))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Do not use `bookmark-bmenu-ensure-position' as a test - it always returns non-nil anyway.
+;;    And don't call it again the end.
+;; 2. Use `bmkp-delete-bookmark-name-from-list', not `delete'.
+;; 3. Use face `bmkp-D-mark' on the `D' flag.
+;; 4. Raise error if not in buffer `*Bookmark List*'.
+;; 5. Remove bookmark from `bmkp-bmenu-marked-bookmarks'.  Add it to `bmkp-flagged-bookmarks'.
+;; 6. Call `bmkp-bmenu-mode-line'.
+;;
+;;;###autoload (autoload 'bmkp-bmenu-flag-for-deletion "bookmark+")
+(defalias 'bmkp-bmenu-flag-for-deletion 'bookmark-bmenu-delete) ; A better name.
+;;;###autoload (autoload 'bookmark-bmenu-delete "bookmark+")
+(defun bookmark-bmenu-delete ()         ; Bound to `d', `k' in bookmark list
+  "Flag this bookmark for deletion, using mark `D'.
+Use `\\<bookmark-bmenu-mode-map>\\[bookmark-bmenu-execute-deletions]' to carry out \
+the deletions."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (beginning-of-line)
+  (bookmark-bmenu-ensure-position)
+  (with-buffer-modified-unmodified
+      (let ((inhibit-read-only  t))
+        (delete-char 1) (insert ?D) (put-text-property (1- (point)) (point) 'face 'bmkp-D-mark)))
+  (when (bookmark-bmenu-bookmark)       ; Should never be nil, but just to be safe.
+    (setq bmkp-bmenu-marked-bookmarks  (bmkp-delete-bookmark-name-from-list
+                                        (bookmark-bmenu-bookmark) bmkp-bmenu-marked-bookmarks))
+    ;; This is the same as `add-to-list' with `eq' (not available for Emacs 20-21).
+    (let ((bmk  (bmkp-bookmark-record-from-name (bookmark-bmenu-bookmark))))
+      (unless (memq bmk bmkp-flagged-bookmarks)
+        (setq bmkp-flagged-bookmarks  (cons bmk bmkp-flagged-bookmarks)))))
+  (forward-line 1)
+  (when (fboundp 'bmkp-bmenu-mode-line) (bmkp-bmenu-mode-line)))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; Do not move forward another line at end.  Leave point above flagged bookmark.
+;;
+;;;###autoload (autoload 'bmkp-bmenu-flag-for-deletion-backwards "bookmark+")
+(defalias 'bmkp-bmenu-flag-for-deletion-backwards 'bookmark-bmenu-delete-backwards) ; A better name.
+;;;###autoload (autoload 'bookmark-bmenu-delete-backwards "bookmark+")
+(defun bookmark-bmenu-delete-backwards ()
+  "Mark bookmark on this line to be deleted, then move up one line.
+To carry out the deletions that you've marked, use \\<bookmark-bmenu-mode-map>\
+\\[bookmark-bmenu-execute-deletions]."
+  (interactive)
+  (bookmark-bmenu-delete)
+  (forward-line -2)
+  (bookmark-bmenu-ensure-position))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Added optional arg NO-MSG-P.
+;; 2. Rebuild the menu list using the last filtered alist in use, `bmkp-latest-bookmark-alist'.
+;; 3. Update the menu-list title.
+;;
+(defun bookmark-bmenu-surreptitiously-rebuild-list (&optional no-msg-p)
+  "Rebuild the bookmark list, if it exists.
+Non-nil optional arg NO-MSG-P means do not show progress messages."
+  (when (get-buffer bmkp-bmenu-buffer)
+    (unless no-msg-p (message "Updating bookmark-list display..."))
+    (save-excursion (save-window-excursion (let ((bookmark-alist  bmkp-latest-bookmark-alist))
+                                             (bookmark-bmenu-list 'filteredp))))
+    (unless no-msg-p (message "Updating bookmark-list display...done"))))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Added arg FILTEREDP.
+;; 2. Handles also region bookmarks and buffer (non-file) bookmarks.
+;; 3. Uses `pop-to-buffer', not `switch-to-buffer', so we respect `special-display-*'
+;;    (but keep `one-window-p' if that's the case).
+;; 4. If option `bmkp-bmenu-state-file' is non-nil, then the first time since the last quit
+;;     (or the last Emacs session) restores the last menu-list state.
+;; 5. If option `bmkp-bmenu-commands-file' is non-nil, then read that file, which contains
+;;    user-defined `*Bookmark List*' commands.
+;; 6. Many differences in the display itself - see the doc.
+;;
+;;;###autoload (autoload 'list-bookmarks "bookmark+")
+(defalias 'list-bookmarks 'bookmark-bmenu-list)
+;;;###autoload (autoload 'bookmark-bmenu-list "bookmark+")
+(defun bookmark-bmenu-list (&optional filteredp msg-p) ; Bound to `C-x x e', `C-x r l'
+  "Display a list of existing bookmarks, in buffer `*Bookmark List*'.
+The leftmost column of a bookmark entry shows `D' if the bookmark is
+ flagged for deletion, or `>' if it is marked normally.
+The second column shows `t' if the bookmark has tags.
+The third  column shows `a' if the bookmark has an annotation.
+
+The following faces are used for the list entries.
+Use `customize-face' if you want to change the appearance.
+
+ `bmkp-bad-bookmark', `bmkp-bookmark-file', `bmkp-bookmark-list',
+ `bmkp-buffer', `bmkp-desktop', `bmkp-file-handler', `bmkp-function',
+ `bmkp-gnus', `bmkp-info', `bmkp-local-directory',
+ `bmkp-local-file-without-region', `bmkp-local-file-with-region',
+ `bmkp-man', `bmkp-no-jump', `bmkp-no-local', `bmkp-non-file',
+ `bmkp-remote-file', `bmkp-sequence', `bmkp-snippet',
+ `bmkp-su-or-sudo', `bmkp-url', `bmkp-variable-list'
+
+If option `bmkp-bmenu-state-file' is non-nil then the state of the
+displayed bookmark-list is saved when you quit it, and it is restored
+when you next use this command.  That saved state is not restored,
+however, if it represents a different file from the current bookmark
+file.
+
+If you call this interactively when buffer `*Bookmark List*' exists,
+that buffer is refreshed to show all current bookmarks, and any
+markings are removed.  If you instead want to show the buffer in its
+latest state then just do that: use `C-x b' or similar.  If you want
+to refresh the displayed buffer, to show the latest state, reflecting
+any additions, deletions, renamings, and so on, use \\<bookmark-bmenu-mode-map>\
+`\\[bmkp-bmenu-refresh-menu-list]'.
+
+
+Non-interactively:
+
+ - Non-nil optional argument FILTEREDP means the bookmark list has
+   been filtered, which means:
+
+   * Use `bmkp-bmenu-title' not the default menu-list title.
+   * Do not reset `bmkp-latest-bookmark-alist' to `bookmark-alist'.
+
+ - Non-nil optional arg MSG-P means display progress messages."
+  (interactive "i\np")
+  (bookmark-maybe-load-default-file)
+  (when msg-p (message "Gathering bookmarks to display..."))
+  (when (and bmkp-bmenu-first-time-p  bmkp-bmenu-commands-file
+             (file-readable-p bmkp-bmenu-commands-file))
+    (when (file-directory-p bmkp-bmenu-commands-file)
+      (error "`%s' is a directory, not a file" bmkp-bmenu-commands-file))
+    (with-current-buffer (let ((enable-local-variables  ())
+                               (emacs-lisp-mode-hook    nil))
+                           (find-file-noselect bmkp-bmenu-commands-file))
+      (goto-char (point-min))
+      (while (not (eobp)) (condition-case nil (eval (read (current-buffer))) (error nil)))
+      (kill-buffer (current-buffer))))
+  (cond ((and bmkp-bmenu-first-time-p  bmkp-bmenu-state-file ; Restore from state file.
+              (file-readable-p bmkp-bmenu-state-file))
+         (when (file-directory-p bmkp-bmenu-state-file)
+           (error "`%s' is a directory, not a file" bmkp-bmenu-state-file))
+         (let ((state  ()))
+           (with-current-buffer (let ((enable-local-variables  nil)
+                                      (emacs-lisp-mode-hook    nil))
+                                  (find-file-noselect bmkp-bmenu-state-file))
+             (goto-char (point-min))
+             (setq state  (condition-case nil (read (current-buffer)) (error nil)))
+             (kill-buffer (current-buffer)))
+           (let ((last-bookmark-file-from-state  (cdr (assq 'last-bookmark-file state))))
+             (when (and (consp state)
+                        ;; If bookmark file has changed, then do not use state saved from other file.
+                        (or (not last-bookmark-file-from-state)
+                            (bmkp-same-file-p last-bookmark-file-from-state
+                                              bmkp-current-bookmark-file)))
+               (setq bmkp-sort-comparer                (cdr (assq 'last-sort-comparer                state))
+                     bmkp-reverse-sort-p               (cdr (assq 'last-reverse-sort-p               state))
+                     bmkp-reverse-multi-sort-p         (cdr (assq 'last-reverse-multi-sort-p         state))
+                     bmkp-latest-bookmark-alist        (cdr (assq 'last-latest-bookmark-alist        state))
+                     bmkp-bmenu-omitted-bookmarks      (cdr (assq 'last-bmenu-omitted-bookmarks      state))
+                     bmkp-bmenu-marked-bookmarks       (cdr (assq 'last-bmenu-marked-bookmarks       state))
+                     bmkp-bmenu-filter-function        (cdr (assq 'last-bmenu-filter-function        state))
+                     bmkp-bmenu-filter-pattern         (or (cdr (assq 'last-bmenu-filter-pattern     state))
+                                                           "")
+                     bmkp-bmenu-title                  (cdr (assq 'last-bmenu-title                  state))
+                     bmkp-last-bmenu-bookmark          (cdr (assq 'last-bmenu-bookmark               state))
+                     bmkp-last-specific-buffer         (cdr (assq 'last-specific-buffer              state))
+                     bmkp-last-specific-file           (cdr (assq 'last-specific-file                state))
+                     bookmark-bmenu-toggle-filenames   (cdr (assq 'last-bmenu-toggle-filenames       state))
+                     bmkp-last-bookmark-file           (or  (cdr (assq 'last-previous-bookmark-file  state))
+                                                            bmkp-current-bookmark-file)
+                     bmkp-current-bookmark-file        last-bookmark-file-from-state
+                     bmkp-bmenu-before-hide-marked-alist
+                     (cdr (assq 'last-bmenu-before-hide-marked-alist   state))
+                     bmkp-bmenu-before-hide-unmarked-alist
+                     (cdr (assq 'last-bmenu-before-hide-unmarked-alist state))))))
+         (setq bmkp-bmenu-first-time-p  nil)
+         (let ((bookmark-alist  (bmkp-refresh-latest-bookmark-list))) ; This sets *-latest-* also.
+           (bmkp-bmenu-list-1 'filteredp nil msg-p))
+         ;; Propertize bookmark names if not already propertized (lists saved with Emacs 20 or
+         ;; not `bmkp-propertize-bookmark-names-flag').  Check only the first, to guess propertized.
+         (when (and (consp bmkp-bmenu-marked-bookmarks)
+                    (not (get-text-property 0 'bmkp-full-record (car bmkp-bmenu-marked-bookmarks))))
+           (setq bmkp-bmenu-marked-bookmarks
+                 (condition-case nil
+                     (mapcar (lambda (bname)
+                               (if (get-text-property 0 'bmkp-full-record bname)
+                                   bname
+                                 (put-text-property 0 (length bname) 'bmkp-full-record
+                                                    (bmkp-bookmark-record-from-name bname) bname)
+                                 bname))
+                             bmkp-bmenu-marked-bookmarks)
+                   (error ()))))        ; Reset to () if any name is not a current bookmark.
+         (when (and (consp bmkp-bmenu-omitted-bookmarks)
+                    (not (get-text-property 0 'bmkp-full-record (car bmkp-bmenu-omitted-bookmarks))))
+           (setq bmkp-bmenu-omitted-bookmarks
+                 (condition-case nil
+                     (mapcar (lambda (bname)
+                               (if (get-text-property 0 'bmkp-full-record bname)
+                                   bname
+                                 (put-text-property 0 (length bname) 'bmkp-full-record
+                                                    (bmkp-bookmark-record-from-name bname) bname)
+                                 bname))
+                             bmkp-bmenu-omitted-bookmarks)
+                   (error ()))))        ; Reset to () if any name is not a current bookmark.
+         (when bmkp-last-bmenu-bookmark
+           (with-current-buffer (get-buffer bmkp-bmenu-buffer)
+             (bmkp-bmenu-goto-bookmark-named bmkp-last-bmenu-bookmark))))
+        (t
+         (setq bmkp-bmenu-first-time-p  nil)
+         (bmkp-bmenu-list-1 filteredp (or msg-p  (not (get-buffer bmkp-bmenu-buffer))) msg-p))))
+
+(defun bmkp-bmenu-list-1 (filteredp reset-p interactivep)
+  "Helper for `bookmark-bmenu-list'.
+See `bookmark-bmenu-list' for the description of FILTEREDP.
+Reset `bmkp-modified-bookmarks' and `bmkp-flagged-bookmarks'.
+Non-nil RESET-P means reset `bmkp-bmenu-marked-bookmarks' also.
+Non-nil INTERACTIVEP means `bookmark-bmenu-list' was called
+ interactively, so pop to bookmark list and communicate sort order."
+  (setq bmkp-modified-bookmarks  ()
+        bmkp-flagged-bookmarks   ())
+  (when reset-p (setq bmkp-bmenu-marked-bookmarks  ()))
+;; $$$$$$ Took out 2015/01/22. (unless filteredp (setq bmkp-latest-bookmark-alist  bookmark-alist))
+  (if interactivep
+      (let ((one-win-p  (one-window-p)))
+        (pop-to-buffer (get-buffer-create bmkp-bmenu-buffer))
+        (when one-win-p (delete-other-windows)))
+    (set-buffer (get-buffer-create bmkp-bmenu-buffer)))
+  (let* ((inhibit-read-only       t)
+         (title                   (if (and filteredp bmkp-bmenu-title  (not (equal "" bmkp-bmenu-title)))
+                                      bmkp-bmenu-title
+                                    "All Bookmarks"))
+         (show-image-file-icon-p  (and (fboundp 'display-images-p)  (display-images-p)
+                                       bmkp-bmenu-image-bookmark-icon-file
+                                       (file-readable-p bmkp-bmenu-image-bookmark-icon-file))))
+    (erase-buffer)
+    (when (fboundp 'remove-images) (remove-images (point-min) (point-max)))
+    (insert (format "%s\n%s\n" title (make-string (length title) ?-)))
+    (add-text-properties (point-min) (point) (bmkp-face-prop 'bmkp-heading))
+    (goto-char (point-min))
+    (insert (format "Bookmark file:\n%s\n\n" bmkp-current-bookmark-file))
+    (forward-line bmkp-bmenu-header-lines)
+    (let ((max-width  0)
+          name markedp flaggedp tags annotation temporaryp start)
+      (setq bmkp-sorted-alist  (bmkp-sort-omit bookmark-alist
+                                               (and (not (eq bmkp-bmenu-filter-function
+                                                             'bmkp-omitted-alist-only))
+                                                    bmkp-bmenu-omitted-bookmarks)))
+      (dolist (bmk  bmkp-sorted-alist)
+        (setq max-width  (max max-width (string-width (bmkp-bookmark-name-from-record bmk)))))
+      (setq max-width  (+ max-width bmkp-bmenu-marks-width))
+      (dolist (bmk  bmkp-sorted-alist)
+        (setq name        (bmkp-bookmark-name-from-record bmk)
+              markedp     (bmkp-marked-bookmark-p bmk)
+              flaggedp    (bmkp-flagged-bookmark-p bmk)
+              tags        (bmkp-get-tags bmk)
+              annotation  (bookmark-get-annotation bmk)
+              start       (+ bmkp-bmenu-marks-width (point)))
+        (cond (flaggedp (insert "D") (put-text-property (1- (point)) (point) 'face 'bmkp-D-mark))
+              (markedp  (insert ">") (put-text-property (1- (point)) (point) 'face 'bmkp->-mark))
+              (t        (insert " ")))
+        (if (null tags)
+            (insert " ")
+          (insert "t") (put-text-property (1- (point)) (point) 'face 'bmkp-t-mark))
+        (cond ((bmkp-temporary-bookmark-p bmk)
+               (insert "X") (put-text-property (1- (point)) (point) 'face 'bmkp-X-mark))
+              ((and annotation  (not (string-equal annotation "")))
+               (insert "a") (put-text-property (1- (point)) (point) 'face 'bmkp-a-mark))
+              (t (insert " ")))
+        (if (not (memq bmk bmkp-modified-bookmarks))
+            (insert " ")
+          (insert "*")
+          (put-text-property (1- (point)) (point) 'face 'bmkp-*-mark))
+        (when (and (featurep 'bookmark+-lit)  (bmkp-get-lighting bmk)) ; Highlight highlight overrides.
+          (put-text-property (1- (point)) (point) 'face 'bmkp-light-mark))
+        (when (and (bmkp-image-bookmark-p bmk)  show-image-file-icon-p)
+          (let ((image  (create-image bmkp-bmenu-image-bookmark-icon-file nil nil :ascent 95)))
+            (when image (put-image image (point)))))
+        (insert name)
+        (move-to-column max-width t)
+        (bmkp-bmenu-propertize-item bmk start (point))
+        (insert "\n")))
+    (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines)
+    (bookmark-bmenu-mode)
+    (when (and bookmark-alist  bookmark-bmenu-toggle-filenames)
+      (bookmark-bmenu-toggle-filenames t 'NO-MSG-P))
+    (when (and (fboundp 'fit-frame-if-one-window)
+               (eq (selected-window) (get-buffer-window (get-buffer-create bmkp-bmenu-buffer) 0)))
+      (fit-frame-if-one-window)))
+  (when (fboundp 'bmkp-bmenu-mode-line) (bmkp-bmenu-mode-line))
+  (when (and interactivep  bmkp-sort-comparer) (bmkp-msg-about-sort-order (bmkp-current-sort-order))))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; Redefined.
+;; 1. Get name of the current bookmark from text property `bmkp-bookmark-name'.
+;; 2. Added optional arg FULL, to return full bookmark record.
+;; 3. Use `condition-case' in case we're at eob (so cannot advance).
+;;
+(defun bookmark-bmenu-bookmark (&optional full)
+  "Return the name of the bookmark on this line.
+Normally, the string returned is propertized with property
+`bmkp-full-record', which records the full bookmark record.
+Return nil if no bookmark on this line.
+Non-nil optional FULL means return the bookmark record, not the name."
+  (condition-case nil
+      (let ((name  (save-excursion (forward-line 0) (forward-char bmkp-bmenu-marks-width)
+                                   (get-text-property (point) 'bmkp-bookmark-name))))
+        (if full (get-text-property 0 'bmkp-full-record name) name))
+    (error nil)))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Mode-line major-mode name is different, and indicates whether in temporary bookmarking minor mode.
+;; 2. Doc string is different.
+;;
+(defun bookmark-bmenu-mode ()
+  "Major mode for editing a list of bookmarks.
+
+Each line represents an Emacs bookmark.  Keys without prefix `C-x' are
+available only here (in `*Bookmark List*').  Other keys are available
+everywhere.
+
+Remember that you can see all bindings for a prefix key by hitting it,
+then `C-h'.  E.g., `s C-h' to see keys with prefix `s' (sorting keys).
+
+More bookmarking help below.
+
+
+Help - Bookmark Info
+--------------------
+
+\\<bookmark-bmenu-mode-map>\
+\\[bookmark-bmenu-toggle-filenames]\t- Toggle showing filenames next to bookmarks
+\\[bmkp-bmenu-describe-this-bookmark]\t- Show information about bookmark       (`C-u': internal form)
+\\[bmkp-bmenu-describe-this+move-down]\t- Show the info, then move to next bookmark
+\\[bmkp-bmenu-describe-this+move-up]\t- Show the info, then move to previous bookmark
+\\[bmkp-bmenu-describe-marked]\t- Show info about the marked bookmarks  (`C-u': internal form)
+\\[bookmark-bmenu-locate]\t- Show location of bookmark (in minibuffer)
+\\[bookmark-bmenu-show-annotation]\t- Show bookmark's annotation
+\\[bookmark-bmenu-show-all-annotations]\t- Show the annotations of all annotated bookmarks
+
+\\[bmkp-list-defuns-in-commands-file]
+\t- List the commands defined in `bmkp-bmenu-commands-file'
+
+
+Bookmark-List Display (`*Bookmark List*')
+-----------------------------------------
+
+\\[bmkp-toggle-saving-menu-list-state]\t- Toggle autosaving bookmark-list display state
+\\[bmkp-save-menu-list-state]\t- Save bookmark-list display state
+
+\\[bmkp-bmenu-refresh-menu-list]\t- Refresh display to current bookmark list  (`C-u': from file)
+\\[bmkp-bmenu-show-all]\t- Show all bookmarks
+\\[bmkp-toggle-bookmark-set-refreshes]
+\t- Toggle whether `bookmark-set' refreshes the bookmark list
+\\[bmkp-bmenu-mode-status-help]\t- Show this help
+\\[bmkp-bmenu-quit]\t- Quit (`*Bookmark List*')
+
+
+Bookmark Files
+--------------
+
+\\[bmkp-toggle-saving-bookmark-file]\t- Toggle autosaving to the current bookmark file
+\\[bookmark-bmenu-save]\t- Save bookmarks now     (`C-u': Save As... - prompt for file)
+\\[bmkp-empty-file]\t- Empty existing bookmark file or create new, empty one
+
+C-u \\[bmkp-bmenu-refresh-menu-list]\t- Revert to bookmarks in the bookmark file    (overwrite load)
+\\[bmkp-switch-bookmark-file-create]\t- Switch to a different bookmark file         (overwrite load)
+C-u \\[bmkp-switch-bookmark-file-create]\t- Switch back to the previous bookmark file   (overwrite load)
+\\[bookmark-bmenu-load]\t- Add bookmarks from a different bookmark file    (extra load)
+\\[bmkp-bmenu-load-marked-bookmark-file-bookmarks]\t- Load marked bookmark-file bookmarks             \
+\(extra load)
+
+\\[bmkp-bmenu-move-marked-to-bookmark-file]\t- Move the marked bookmarks to a bookmark file
+\\[bmkp-bmenu-copy-marked-to-bookmark-file]\t- Copy the marked bookmarks to a bookmark file
+\\[bmkp-bmenu-create-bookmark-file-from-marked]\t- Copy the marked bookmarks to a new bookmark file
+C-u \\[bmkp-bmenu-create-bookmark-file-from-marked]\t- Same, plus create bookmark-file bookmark for it
+
+
+General
+-------
+
+Here:
+
+\\[bmkp-bmenu-dired-marked]\t- Open Dired for the marked file and directory bookmarks
+\\[bmkp-bmenu-make-sequence-from-marked]
+\t- Create a sequence bookmark from the marked bookmarks
+\\[bmkp-temporary-bookmarking-mode]\t- Toggle temporary-only bookmarking (new, empty bookmark file)
+
+Anywhere:
+
+\\<global-map>\
+\\[bmkp-toggle-autotemp-on-set]\t- Toggle making bookmarks temporary when setting them
+\\[bmkp-set-bookmark-file-bookmark]\t- Create a bookmark to a bookmark file (`j y' to load it)
+\\[bmkp-delete-bookmarks]\t- Delete some bookmarks at point or all in buffer
+\\[bmkp-make-function-bookmark]\t- Create a function bookmark
+
+\\[bmkp-choose-navlist-of-type]\t- Set the navlist to the bookmarks of a type you choose
+\\[bmkp-choose-navlist-from-bookmark-list]\t- Set the navlist to the bookmarks of a \
+bookmark-list bookmark
+\\[bmkp-navlist-bmenu-list]\t- Open `*Bookmark List*' for bookmarks in navlist
+
+\\[bmkp-this-file/buffer-bmenu-list]\t- Open `*Bookmark List*' for bookmarks in current file/buffer
+\\[bmkp-switch-to-bookmark-file-this-file/buffer]\t- Switch to bookmark file for current file/buffer
+\\[bmkp-save-bookmarks-this-file/buffer]\t- Save bookmarks for current file/buffer to a file
+\\<bookmark-bmenu-mode-map>
+
+
+Create/Set Bookmarks (anywhere)
+--------------------
+
+\\[bmkp-toggle-autonamed-bookmark-set/delete]\t- Set/delete an autonamed bookmark here
+\\[bmkp-autofile-set]\t- Set and autoname a bookmark for a file
+\\[bmkp-file-target-set]\t- Set a bookmark for a file
+\\[bmkp-url-target-set]\t- Set a bookmark for a URL
+\\[bmkp-bookmark-set-confirm-overwrite]\t\t- Set a bookmark here
+\\[bmkp-set-desktop-bookmark]\t\t- Set a bookmark for the current desktop
+\\[bmkp-set-bookmark-file-bookmark]\t\t- Set a bookmark for a bookmark file
+\\[bmkp-set-snippet-bookmark]\t- Save the region text as a snippet bookmark
+
+
+Jump to (Visit) Bookmarks
+-------------------------
+
+\\[bookmark-bmenu-this-window]\t- This bookmark in the same window
+\\[bookmark-bmenu-other-window]\t- This bookmark in another window
+\\[bookmark-bmenu-switch-other-window]\t- This bookmark in other window, without selecting it
+\\[bookmark-bmenu-2-window]\t- This bookmark and last-visited bookmark
+\\[bookmark-bmenu-1-window]\t- This bookmark in a full-frame window
+\\[bookmark-bmenu-other-frame]\t- This bookmark in another frame
+
+\\[bmkp-bmenu-jump-to-marked]\t- Bookmarks marked `>', in other windows
+
+Prefix `j' uses another window; prefix `J' reuses this window:
+
+\\[bookmark-jump-other-window]\t- Bookmark by name
+\\[bmkp-jump-in-navlist-other-window]\t- Bookmark in the navigation list
+\\[bmkp-lighted-jump-other-window]\t- Highlighted bookmark
+
+\\[bmkp-jump-to-type-other-window]\t- Bookmark by type
+\\[bmkp-autonamed-jump-other-window]\t- Autonamed bookmark
+\\[bmkp-autonamed-this-buffer-jump-other-window]\t- Autonamed bookmark in this buffer
+\\[bmkp-temporary-jump-other-window]\t- Temporary bookmark
+
+\\[bmkp-autofile-jump-other-window]\t- Autofile bookmark
+\\[bmkp-dired-jump-other-window]\t- Dired bookmark
+\\[bmkp-file-jump-other-window]\t- File or directory bookmark
+\\[bmkp-dired-this-dir-jump-other-window]\t- Dired bookmark for this dir
+\\[bmkp-file-this-dir-jump-other-window]\t- Bookmark for a file or subdir in this dir
+\\[bmkp-local-file-jump-other-window]\t- Local-file bookmark
+\\[bmkp-remote-file-jump-other-window]\t- Remote-file bookmark
+\\[bmkp-non-file-jump-other-window]\t- Non-file (buffer) bookmark
+
+\\[bmkp-desktop-jump]\t- Desktop bookmark
+\\[bmkp-bookmark-list-jump]\t- Bookmark-list bookmark
+\\[bmkp-bookmark-file-jump]\t- Bookmark-file bookmark
+
+\\[bmkp-region-jump-other-window]\t- Region bookmark (restore region)
+\\[bmkp-snippet-to-kill-ring]\t- Snippet bookmark (copy to `kill-ring')
+\\[bmkp-image-jump-other-window]\t- Image-file bookmark
+\\[bmkp-info-jump-other-window]\t- Info bookmark
+\\[bmkp-man-jump-other-window]\t- `man'-page bookmark
+\\[bmkp-gnus-jump-other-window]\t- Gnus bookmark
+\\[bmkp-url-jump-other-window]\t- URL bookmark
+\\[bmkp-variable-list-jump]\t- Variable-list bookmark
+
+\\[bmkp-some-tags-jump-other-window]\t- Bookmark having some tags you specify
+\\[bmkp-all-tags-jump-other-window]\t- Bookmark having each tag you specify
+\\[bmkp-some-tags-regexp-jump-other-window]\t- Bookmark having a tag that matches a regexp
+\\[bmkp-all-tags-regexp-jump-other-window]\t- Bookmark having all its tags match a regexp
+\\[bmkp-file-some-tags-jump-other-window]\t- File bookmark having some tags you specify
+\\[bmkp-file-all-tags-jump-other-window]\t- File bookmark having each tag you specify
+\\[bmkp-file-some-tags-regexp-jump-other-window]\t- File bookmark having a tag that matches a regexp
+\\[bmkp-file-all-tags-regexp-jump-other-window]\t- File bookmark having all its tags match a regexp
+\\[bmkp-file-this-dir-some-tags-jump-other-window]\t- File in this dir having some tags you specify
+\\[bmkp-file-this-dir-all-tags-jump-other-window]\t- File in this dir having each tag you specify
+\\[bmkp-file-this-dir-some-tags-regexp-jump-other-window]\t- \
+File in this dir having a tag that matches a regexp
+\\[bmkp-file-this-dir-all-tags-regexp-jump-other-window]\t- \
+File in this dir having all its tags match a regexp
+
+
+Autonamed Bookmarks
+-------------------
+
+\\[bmkp-toggle-autonamed-bookmark-set/delete]\t- Create/delete autonamed bookmark at point
+C-u \\[bmkp-toggle-autonamed-bookmark-set/delete]\t- Delete all autonamed bookmarks in current buffer
+\\[bmkp-autonamed-jump-other-window]\t\t- Jump to an autonamed bookmark
+\\[bmkp-autonamed-this-buffer-jump-other-window]\t\t- Jump to an autonamed bookmark in a given buffer
+
+
+Cycle Bookmarks (anywhere)
+---------------
+
+\\[bmkp-next-bookmark-this-file/buffer-repeat]...\t- Next bookmark in buffer         (C-x x n, C-x x C-n)
+\\[bmkp-previous-bookmark-this-file/buffer-repeat]...\t- Prev bookmark in buffer         (C-x x p, \
+C-x x C-p)
+\\[bmkp-next-bookmark-repeat]...- Next bookmark in navlist        (C-x x f, C-x x C-f)
+\\[bmkp-previous-bookmark-repeat]...\t- Prev bookmark in navlist        (C-x x b, C-x x C-b)
+\\[bmkp-next-bookmark-w32-repeat]...\t- MS Windows `Open' next     in navlist   (C-x x next)
+\\[bmkp-previous-bookmark-w32-repeat]...- MS Windows `Open' previous in navlist  (C-x x prior)
+\\[bmkp-next-lighted-this-buffer-repeat]...- Next highlighted bookmark in buffer  (C-x x C-down)
+\\[bmkp-previous-lighted-this-buffer-repeat]...\t- Prev highlighted bookmark in buffer     (C-x x C-up)
+
+ Similar, but not bound to keys by default:
+  \\[bmkp-next-autonamed-bookmark-repeat]        (and `previous')
+  \\[bmkp-next-bookmark-list-bookmark-repeat]    (and `previous')
+  \\[bmkp-next-desktop-bookmark-repeat]          (and `previous')
+  \\[bmkp-next-dired-bookmark-repeat]            (and `previous')
+  \\[bmkp-next-eww-bookmark-repeat]              (and `previous')
+  \\[bmkp-next-file-bookmark-repeat]             (and `previous')
+  \\[bmkp-next-gnus-bookmark-repeat]             (and `previous')
+  \\[bmkp-next-info-bookmark-repeat]             (and `previous')
+  \\[bmkp-next-lighted-bookmark-repeat]          (and `previous')
+  \\[bmkp-next-local-file-bookmark-repeat]       (and `previous')
+  \\[bmkp-next-man-bookmark-repeat]              (and `previous')
+  \\[bmkp-next-non-file-bookmark-repeat]         (and `previous')
+  \\[bmkp-next-remote-file-bookmark-repeat]      (and `previous')
+  \\[bmkp-next-specific-buffers-bookmark-repeat] (and `previous')
+  \\[bmkp-next-specific-files-bookmark-repeat]   (and `previous')
+  \\[bmkp-next-url-bookmark-repeat]              (and `previous')
+  \\[bmkp-next-variable-list-bookmark-repeat]    (and `previous')
+
+
+Search-and-Replace in Bookmark Targets (here, in sort order)
+--------------------------------------
+
+\\[bmkp-bmenu-isearch-marked-bookmarks]\t- Isearch the marked bookmarks            (`C-u': all)
+\\[bmkp-bmenu-isearch-marked-bookmarks-regexp]\t- Regexp-isearch the marked bookmarks     (`C-u': all)
+\\[bmkp-bmenu-search-marked-bookmarks-regexp]\t- Regexp-search the marked file bookmarks (`C-u': all)
+\\[bmkp-bmenu-query-replace-marked-bookmarks-regexp]\t\t- Query-replace the marked file bookmarks
+
+
+Mark/Unmark Bookmarks
+---------------------
+
+\(Mark means `>'.  Flag means `D'.   See also `Tags', below.)
+
+\\[bmkp-bmenu-flag-for-deletion]\t- Flag bookmark `D' for deletion, then move down
+\\[bmkp-bmenu-flag-for-deletion-backwards]\t- Flag bookmark `D' for deletion, then move up
+
+\\[bookmark-bmenu-mark]\t- Mark bookmark
+\\[bookmark-bmenu-unmark]\t- Unmark bookmark                    (`C-u': move up one line)
+\\[bookmark-bmenu-backup-unmark]\t- Unmark previous bookmark (move up, then unmark)
+
+\\[bmkp-bmenu-mark-all]\t- Mark all bookmarks
+\\[bmkp-bmenu-regexp-mark]\t- Mark all bookmarks whose names match a regexp
+\\[bmkp-bmenu-unmark-all]\t- Unmark all bookmarks              (`C-u': interactive query)
+\\[bmkp-bmenu-toggle-marks]\t- Toggle marks: unmark the marked and mark the unmarked
+
+\\[bmkp-bmenu-mark-autofile-bookmarks]\t- Mark autofile bookmarks
+\\[bmkp-bmenu-mark-autonamed-bookmarks]\t- Mark autonamed bookmarks
+\\[bmkp-bmenu-mark-temporary-bookmarks]\t- Mark temporary bookmarks
+\\[bmkp-bmenu-mark-lighted-bookmarks]\t- Mark highlighted bookmarks (requires `bookmark+-lit.el)
+
+\\[bmkp-bmenu-mark-non-file-bookmarks]\t- Mark non-file (i.e. buffer) bookmarks
+\\[bmkp-bmenu-mark-dired-bookmarks]\t- Mark Dired bookmarks
+\\[bmkp-bmenu-mark-file-bookmarks]\t- Mark file & directory bookmarks          (`C-u': local only)
+\\[bmkp-bmenu-mark-gnus-bookmarks]\t- Mark Gnus bookmarks
+\\[bmkp-bmenu-mark-info-bookmarks]\t- Mark Info bookmarks
+\\[bmkp-bmenu-mark-icicles-search-hits-bookmarks]\t- Mark Icicles search-hits bookmarks
+\\[bmkp-bmenu-mark-non-invokable-bookmarks]\t- Mark non-invokable bookmarks
+\\[bmkp-bmenu-mark-image-bookmarks]\t- Mark image-file bookmarks
+\\[bmkp-bmenu-mark-desktop-bookmarks]\t- Mark desktop bookmarks
+\\[bmkp-bmenu-mark-man-bookmarks]\t- Mark `man' page bookmarks (that's `M' twice, not Meta-M)
+\\[bmkp-bmenu-mark-orphaned-local-file-bookmarks]\t- Mark orphaned local file/dir bookmarks  (`C-u': \
+remote also)
+\\[bmkp-bmenu-mark-region-bookmarks]\t- Mark region bookmarks
+\\[bmkp-bmenu-mark-function-bookmarks]\t- Mark function bookmarks
+\\[bmkp-bmenu-mark-url-bookmarks]\t- Mark URL bookmarks
+\\[bmkp-bmenu-mark-variable-list-bookmarks]\t- Mark variable-list bookmarks
+\\[bmkp-bmenu-mark-w3m-bookmarks]\t- Mark W3M (URL) bookmarks
+\\[bmkp-bmenu-mark-snippet-bookmarks]\t- Mark snippet bookmarks
+\\[bmkp-bmenu-mark-bookmark-file-bookmarks]\t- Mark bookmark-file bookmarks
+\\[bmkp-bmenu-mark-bookmark-list-bookmarks]\t- Mark bookmark-list bookmarks
+
+
+Modify, Delete Bookmarks
+------------------------
+
+\(See also `Tags', next.)
+
+\\[bmkp-bmenu-edit-bookmark-name-and-location]\t- Rename or relocate bookmark
+\\[bookmark-bmenu-relocate]\t- Relocate bookmark
+\\[bmkp-bmenu-relocate-marked]\t- Relocate marked bookmarks
+\\[bmkp-bmenu-edit-tags]\t- Edit bookmark's tags
+\\[bookmark-bmenu-edit-annotation]\t- Edit bookmark's annotation
+\\[bmkp-bmenu-edit-annotations-for-marked]\t- Edit annotations of marked bookmarks (`C-u': all)
+\\[bmkp-bmenu-edit-bookmark-record]\t- Edit internal Lisp record for bookmark
+\\[bmkp-bmenu-edit-marked]\t- Edit internal Lisp records of marked bookmarks  (`C-u': all)
+\\[bmkp-bmenu-toggle-temporary]\t- Toggle temporary/savable status of bookmark
+\\[bmkp-bmenu-toggle-marked-temporary/savable]\t- Toggle temporary/savable status of marked bookmarks
+\\[bmkp-delete-all-temporary-bookmarks]\t- Delete all temp bookmarks
+\\[bookmark-bmenu-execute-deletions]\t- Delete (visible) bookmarks flagged `D'
+\\[bmkp-bmenu-delete-marked]\t- Delete (visible) bookmarks marked `>'
+
+
+Bookmark Tags
+-------------
+
+Here:
+
+\\[bmkp-bmenu-copy-tags]\t- Copy tags from this bookmark (for subsequent pasting)
+\\[bmkp-bmenu-paste-add-tags]\t- Paste tags (copied from another) to this bookmark
+\\[bmkp-bmenu-paste-replace-tags]\t- Replace tags for this bookmark (with those copied)
+\\[bmkp-add-tags]\t- Add some tags to a bookmark
+\\[bmkp-remove-tags]\t- Remove some tags from a bookmark (`C-u': from all bookmarks)
+\\[bmkp-remove-all-tags]\t- Remove all tags from a bookmark
+\\[bmkp-remove-tags-from-all]\t- Remove some tags from all bookmarks
+\\[bmkp-rename-tag]\t- Rename a tag in all bookmarks
+\\[bmkp-list-all-tags]\t- List all tags used in any bookmarks (`C-u': show tag values)
+\\[bmkp-bmenu-list-tags-of-marked]\t- List tags used in marked bookmarks  (`C-u': show tag values)
+\\[bmkp-bmenu-edit-tags]\t- Edit bookmark's tags
+\\[bmkp-bmenu-set-tag-value]\t- Set the value of a tag (as attribute)
+
+\\[bmkp-bmenu-set-tag-value-for-marked]\t- Set value of a tag, for each marked bookmark    (`C-u': all)
+\\[bmkp-bmenu-paste-add-tags-to-marked]\t- Add tags copied from a bookmark to those marked (`C-u': all)
+\\[bmkp-bmenu-paste-replace-tags-for-marked]\t- Replace tags of marked with copied tags \
+        (`C-u': all)
+\\[bmkp-bmenu-add-tags-to-marked]\t- Add some tags to the marked bookmarks           (`C-u': all)
+\\[bmkp-bmenu-remove-tags-from-marked]\t- Remove some tags from the marked bookmarks      (`C-u': all)
+
+\\[bmkp-bmenu-mark-bookmarks-tagged-regexp]\t- Mark bookmarks having at least one \
+tag that matches a regexp
+\\[bmkp-bmenu-mark-bookmarks-tagged-some]\t- Mark bookmarks having at least one tag \
+in a set    (OR)
+\\[bmkp-bmenu-mark-bookmarks-tagged-all]\t- Mark bookmarks having all of the tags \
+in a set     (AND)
+\\[bmkp-bmenu-mark-bookmarks-tagged-none]\t- Mark bookmarks not having any of the tags \
+in a set (NOT OR)
+\\[bmkp-bmenu-mark-bookmarks-tagged-not-all]\t- Mark bookmarks not having all of the \
+tags in a set (NOT AND)
+
+\\[bmkp-bmenu-unmark-bookmarks-tagged-regexp]\t- Unmark bookmarks having a \
+tag that matches a regexp
+\\[bmkp-bmenu-unmark-bookmarks-tagged-some]\t- Unmark bookmarks having at least one \
+tag in a set  (OR)
+\\[bmkp-bmenu-unmark-bookmarks-tagged-all]\t- Unmark bookmarks having all of the tags \
+in a set   (AND)
+\\[bmkp-bmenu-unmark-bookmarks-tagged-none]\t- Unmark bookmarks not having any tags \
+in a set      (NOT OR)
+\\[bmkp-bmenu-unmark-bookmarks-tagged-not-all]\t- Unmark bookmarks not having all tags \
+in a set      (NOT AND)
+
+Anywhere:
+
+\\<global-map>\
+\\[bmkp-list-all-tags]\t- List all tags
+\\[bmkp-edit-tags]\t- Edit the tags of a bookmark
+\\[bmkp-rename-tag]\t- Rename a tag (everywhere)
+\\[bmkp-copy-tags]\t- Copy tags from a bookmark (for subsequent pasting)
+\\[bmkp-paste-add-tags]\t- Add (paste) tags copied from a bookmark
+\\[bmkp-paste-replace-tags]\t- Replace (paste) a bookmark's tags with copied tags
+\\[bmkp-add-tags]\t- Add some tags to a bookmark
+\\[bmkp-remove-tags]\t- Remove some tags from a bookmark
+\\[bmkp-remove-all-tags]\t- Remove ALL tags from a bookmark
+\\[bmkp-remove-tags-from-all]\t- Remove some tags from ALL bookmarks
+\\[bmkp-tag-a-file]\t- Add tags to a file (create/update autofile bookmark)
+\\[bmkp-untag-a-file]\t- Remove tags from a file (an autofile bookmark)
+\\[bmkp-set-tag-value]\t- Set a tag value for a bookmark
+\\[bmkp-set-tag-value-for-navlist]\t- Set a tag value for each bookmark in navlist
+\\<bookmark-bmenu-mode-map>
+
+
+Bookmark Highlighting
+---------------------
+
+\\[bmkp-bmenu-show-only-lighted-bookmarks]\t- Show only the highlighted bookmarks
+\\[bmkp-bmenu-set-lighting]\t- Set highlighting for bookmark
+\\[bmkp-bmenu-set-lighting-for-marked]\t- Set highlighting for marked bookmarks
+\\[bmkp-bmenu-light]\t- Highlight bookmark
+\\[bmkp-bmenu-unlight]\t- Unhighlight bookmark
+\\[bmkp-bmenu-mark-lighted-bookmarks]\t- Mark the highlighted bookmarks
+\\[bmkp-bmenu-light-marked]\t- Highlight the marked bookmarks
+\\[bmkp-bmenu-unlight-marked]\t- Unhighlight the marked bookmarks
+\\[bmkp-light-bookmark-this-buffer]\t- Highlight a bookmark in current buffer
+\\[bmkp-unlight-bookmark-this-buffer]\t- Unhighlight a bookmark in current buffer
+\\[bmkp-light-bookmarks]\t- Highlight bookmarks (see prefix arg)
+\\[bmkp-unlight-bookmarks]\t- Unhighlight bookmarks (see prefix arg)
+\\[bmkp-bookmarks-lighted-at-point]\t- List bookmarks highlighted at point
+\\[bmkp-unlight-bookmark-here]\t- Unhighlight a bookmark at point or on same line
+\\[bmkp-lighted-jump-other-window]\t- Jump to a highlighted bookmark (other window)
+
+
+Sort `*Bookmark List*' (`s C-h' to see this)
+----------------------
+
+\(Repeat to cycle normal/reversed/off, except as noted.)
+
+\\[bmkp-reverse-sort-order]\t- Reverse current sort direction       (repeat to toggle)
+\\[bmkp-reverse-multi-sort-order]\t- Complement sort predicate decisions  (repeat \
+to toggle)
+\\[bmkp-bmenu-change-sort-order-repeat]\t- Cycle sort orders                    (repeat \
+to cycle)
+
+\\[bmkp-bmenu-sort-marked-before-unmarked]\t- Sort marked (`>') bookmarks first
+\\[bmkp-bmenu-sort-flagged-before-unflagged]\t- Sort flagged (`D') bookmarks first
+\\[bmkp-bmenu-sort-modified-before-unmodified]\t- Sort modified (`*') bookmarks first
+\\[bmkp-bmenu-sort-tagged-before-untagged]\t- Sort tagged (`t') bookmarks first
+\\[bmkp-bmenu-sort-annotated-before-unannotated]\t- Sort annotated (`a') bookmarks first
+
+\\[bmkp-bmenu-sort-by-creation-time]\t- Sort by bookmark creation time
+\\[bmkp-bmenu-sort-by-last-buffer-or-file-access]\t- Sort by last buffer or file \
+access
+\\[bmkp-bmenu-sort-by-last-bookmark-access]\t- Sort by last bookmark access time
+\\[bmkp-bmenu-sort-by-Gnus-thread]\t- Sort by Gnus thread: group, article, message
+\\[bmkp-bmenu-sort-by-Info-node-name]\t- Sort by Info manual, node, position in node
+\\[bmkp-bmenu-sort-by-Info-position]\t- Sort by Info manual, position in manual
+\\[bmkp-bmenu-sort-by-bookmark-type]\t- Sort by bookmark type
+\\[bmkp-bmenu-sort-by-bookmark-name]\t- Sort by bookmark name
+\\[bmkp-bmenu-sort-by-url]\t- Sort by URL
+\\[bmkp-bmenu-sort-by-bookmark-visit-frequency]\t- Sort by bookmark visit frequency
+
+\\[bmkp-bmenu-sort-by-last-local-file-access]\t- Sort by last local file access
+\\[bmkp-bmenu-sort-by-local-file-type]\t- Sort by local file type: file, symlink, dir
+\\[bmkp-bmenu-sort-by-file-name]\t- Sort by file name
+\\[bmkp-bmenu-sort-by-local-file-size]\t- Sort by local file size
+\\[bmkp-bmenu-sort-by-last-local-file-update]\t- Sort by last local file update (edit)
+
+
+Hide/Show (Filtering `*Bookmark List*')
+---------------------------------------
+
+\\[bmkp-bmenu-show-all]\t- Show all bookmarks
+\\[bmkp-bmenu-toggle-show-only-marked]\t- Toggle showing only marked bookmarks
+\\[bmkp-bmenu-toggle-show-only-unmarked]\t- Toggle showing only unmarked bookmarks
+
+\\[bmkp-bmenu-show-only-autonamed-bookmarks]\t- Show only autonamed bookmarks
+\\[bmkp-bmenu-show-only-autofile-bookmarks]\t- Show only autofile bookmarks
+\\[bmkp-bmenu-show-only-temporary-bookmarks]\t- Show only temporary bookmarks
+
+\\[bmkp-bmenu-show-only-non-file-bookmarks]\t- Show only non-file (i.e. buffer) bookmarks
+\\[bmkp-bmenu-show-only-dired-bookmarks]\t- Show only Dired bookmarks
+\\[bmkp-bmenu-show-only-file-bookmarks]\t- Show only file & directory bookmarks     (`C-u': local only)
+\\[bmkp-bmenu-show-only-gnus-bookmarks]\t- Show only Gnus bookmarks
+\\[bmkp-bmenu-show-only-info-bookmarks]\t- Show only Info bookmarks
+\\[bmkp-bmenu-show-only-icicles-search-hits-bookmarks]\t- Show only Icicles search-hits bookmarks
+\\[bmkp-bmenu-show-only-non-invokable-bookmarks]\t- Show only non-invokable bookmarks
+\\[bmkp-bmenu-show-only-image-bookmarks]\t- Show only image-file bookmarks
+\\[bmkp-bmenu-show-only-orphaned-local-file-bookmarks]\t- Show only orphaned local file \
+bookmarks (`C-u': remote also)
+\\[bmkp-bmenu-show-only-desktop-bookmarks]\t- Show only desktop bookmarks
+\\[bmkp-bmenu-show-only-man-bookmarks]\t- Show only `man' page bookmarks
+\\[bmkp-bmenu-show-only-region-bookmarks]\t- Show only region bookmarks
+\\[bmkp-bmenu-show-only-function-bookmarks]\t- Show only function bookmarks
+\\[bmkp-bmenu-show-only-url-bookmarks]\t- Show only URL bookmarks
+\\[bmkp-bmenu-show-only-eww-bookmarks]\t- Show only EWW bookmarks
+\\[bmkp-bmenu-show-only-w3m-bookmarks]\t- Show only W3M bookmarks
+\\[bmkp-bmenu-show-only-variable-list-bookmarks]\t- Show only variable-list bookmarks
+\\[bmkp-bmenu-show-only-tagged-bookmarks]\t- Show only tagged bookmarks
+\\[bmkp-bmenu-show-only-untagged-bookmarks]\t- Show only untagged bookmarks
+\\[bmkp-bmenu-show-only-snippet-bookmarks]\t- Show only snippet bookmarks
+\\[bmkp-bmenu-show-only-bookmark-file-bookmarks]\t- Show only bookmark-file bookmarks
+\\[bmkp-bmenu-show-only-bookmark-list-bookmarks]\t- Show only bookmark-list bookmarks
+
+\\[bmkp-bmenu-filter-annotation-incrementally]\t- Incrementally show bookmarks whose \
+annotations match regexp
+\\[bmkp-bmenu-filter-bookmark-name-incrementally]\t- Incrementally show only bookmarks \
+whose names match a regexp
+\\[bmkp-bmenu-filter-file-name-incrementally]\t- Incrementally show only bookmarks whose \
+files match a regexp
+\\[bmkp-bmenu-filter-tags-incrementally]\t- Incrementally show only bookmarks whose tags \
+match a regexp
+
+
+Omit/Un-omit (`*Bookmark List*')
+--------------------------------
+
+\\[bmkp-bmenu-show-only-omitted-bookmarks]\t- Show (only) the omitted bookmarks
+\\[bmkp-bmenu-show-all]\t- Show the un-omitted bookmarks (all)
+\\[bmkp-bmenu-omit/unomit-marked]\t- Omit the marked bookmarks; un-omit them if after \
+`\\[bmkp-bmenu-show-only-omitted-bookmarks]'
+\\[bmkp-unomit-all]\t- Un-omit all omitted bookmarks
+
+
+Define Commands for `*Bookmark List*'
+-------------------------------------
+
+\\[bmkp-bmenu-define-command]\t- Define a command to restore the current sort order & filter
+\\[bmkp-bmenu-define-full-snapshot-command]\t- Define a command to restore current bookmark list
+\\[bmkp-define-tags-sort-command]\t- Define a command to sort bookmarks by tags
+\\[bmkp-bmenu-define-jump-marked-command]\t- Define a command to jump to a bookmark that is \
+now marked
+
+
+Options for `*Bookmark List*'
+-----------------------------
+
+bookmark-bmenu-file-column       - Bookmark width if files are shown
+bookmark-bmenu-toggle-filenames  - Show filenames initially?
+
+bmkp-bmenu-omitted-bookmarks     - List of omitted bookmarks
+bmkp-bmenu-state-file            - File to save bookmark-list state
+                                   (\"home\") nil: do not save/restore
+bmkp-sort-comparer               - Initial sort
+bmkp-sort-orders-for-cycling-alist - Sort orders that `\\[bmkp-bmenu-change-sort-order-repeat]'... cycles
+
+
+Other Options
+-------------
+
+bookmark-automatically-show-annotations  - Show annotation when visit?
+bookmark-completion-ignore-case  - Case-sensitive completion?
+bookmark-default-file            - File to save bookmarks in
+bookmark-menu-length             - Max size of bookmark-name menu item
+bookmark-save-flag               - Whether and when to save
+bookmark-use-annotations         - Edit annotation when set bookmark?
+bookmark-version-control         - Numbered backups of bookmark file?
+
+bmkp-autoname-format        - Format of autonamed bookmark name
+bmkp-last-as-first-bookmark-file - Whether to start with last b. file
+bmkp-crosshairs-flag        - Highlight position when visit?
+bmkp-menu-popup-max-length  - Use menus to choose bookmarks?
+bmkp-save-new-location-flag - Save if bookmark relocated?
+bmkp-sequence-jump-display-function - How to display a sequence
+bmkp-sort-comparer          - Predicates for sorting bookmarks
+bmkp-su-or-sudo-regexp      - Bounce-show each end of region?
+bmkp-this-file/buffer-cycle-sort-comparer -  cycling sort for here
+bmkp-use-region             - Activate saved region when visit?"
+  (kill-all-local-variables)
+  (use-local-map bookmark-bmenu-mode-map)
+  (setq truncate-lines    t
+        buffer-read-only  t
+        major-mode        'bookmark-bmenu-mode
+        mode-name         (if bmkp-temporary-bookmarking-mode "TEMPORARY Bookmarking" "Bookmarks"))
+  (if (fboundp 'run-mode-hooks)
+      (run-mode-hooks 'bookmark-bmenu-mode-hook)
+    (run-hooks 'bookmark-bmenu-mode-hook)))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Corrected (rewrote).  Toggle var first (unless SHOW).  Call fn according to the var (& to SHOW).
+;; 2. Added optional arg NO-MSG-P.
+;;
+(defun bookmark-bmenu-toggle-filenames (&optional show no-msg-p)
+  "Toggle whether filenames are shown in the bookmark list.
+Toggle the value of `bookmark-bmenu-toggle-filenames', unless SHOW is
+non-nil.
+Optional argument SHOW means show them unconditionally.
+
+Non-nil optional arg NO-MSG-P means do not show progress messages."
+  (interactive)
+  (unless show  (setq bookmark-bmenu-toggle-filenames  (not bookmark-bmenu-toggle-filenames)))
+  (let ((bookmark-bmenu-toggle-filenames  (or show  bookmark-bmenu-toggle-filenames)))
+    (if bookmark-bmenu-toggle-filenames
+        (bookmark-bmenu-show-filenames nil no-msg-p)
+      (bookmark-bmenu-hide-filenames nil no-msg-p))))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Put `mouse-face' on whole line, with the same help-echo as for the bookmark name.
+;; 2. Correct FORCE behavior.
+;; 3. Correct doc string.
+;; 4. Added optional arg NO-MSG-P and progress message.
+;; 5. Fit one-window frame.
+;;
+(defun bookmark-bmenu-show-filenames (&optional force no-msg-p)
+  "Show file names if `bookmark-bmenu-toggle-filenames' is non-nil.
+Otherwise do nothing, except non-nil optional argument FORCE has the
+same effect as non-nil `bookmark-bmenu-toggle-filenames'.  FORCE is
+mainly for debugging.
+Non-nil optional arg NO-MSG-P means do not show progress messages."
+  (when (or force  bookmark-bmenu-toggle-filenames)
+    (unless no-msg-p (message "Showing file names..."))
+    (with-buffer-modified-unmodified
+        (save-excursion
+          (save-window-excursion
+            (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines)
+            (setq bookmark-bmenu-hidden-bookmarks  ())
+            (let ((inhibit-read-only  t))
+              (while (< (point) (point-max))
+                (let ((bmk  (bookmark-bmenu-bookmark)))
+                  (setq bookmark-bmenu-hidden-bookmarks  (cons bmk bookmark-bmenu-hidden-bookmarks))
+                  (move-to-column bookmark-bmenu-file-column t)
+                  (delete-region (point) (line-end-position))
+                  (insert "  ")
+                  (bookmark-insert-location bmk t) ; Pass the NO-HISTORY arg.
+                  (when (if (fboundp 'display-color-p) ; Emacs 21+.
+                            (and (display-color-p)  (display-mouse-p))
+                          window-system)
+                    (let ((help  (get-text-property (+ bmkp-bmenu-marks-width (line-beginning-position))
+                                                    'help-echo)))
+                      (put-text-property (+ bmkp-bmenu-marks-width (line-beginning-position))
+                                         (point) 'mouse-face 'highlight)
+                      (when help  (put-text-property (+ bmkp-bmenu-marks-width (line-beginning-position))
+                                                     (point) 'help-echo help))))
+                  (forward-line 1)))))))
+    (unless no-msg-p (message "Showing file names...done"))
+    (when (and (fboundp 'fit-frame-if-one-window)
+               (eq (selected-window) (get-buffer-window (get-buffer-create bmkp-bmenu-buffer) 0)))
+      (fit-frame-if-one-window))))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Add text properties when hiding filenames.
+;; 2. Do not set or use `bookmark-bmenu-bookmark-column' - use `bmkp-bmenu-marks-width' always.
+;; 3. Correct FORCE behavior.
+;; 4. Correct doc string.
+;; 5. Added optional arg NO-MSG-P and progress message.
+;; 6. Fit one-window frame.
+;;
+(defun bookmark-bmenu-hide-filenames (&optional force no-msg-p)
+  "Hide filenames if `bookmark-bmenu-toggle-filenames' is nil.
+Otherwise do nothing, except non-nil optional argument FORCE has the
+same effect as nil `bookmark-bmenu-toggle-filenames'.  FORCE is mainly
+for debugging.
+Non-nil optional arg NO-MSG-P means do not show progress messages."
+  (when (or force  (not bookmark-bmenu-toggle-filenames))
+    (unless no-msg-p (message "Hiding file names..."))
+    (with-buffer-modified-unmodified
+        (save-excursion
+          (save-window-excursion
+            (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines)
+            (setq bookmark-bmenu-hidden-bookmarks  (nreverse bookmark-bmenu-hidden-bookmarks))
+            (let ((max-width  0))
+              (dolist (name  bookmark-bmenu-hidden-bookmarks)
+                (setq max-width  (max max-width (string-width name))))
+              (setq max-width  (+ max-width bmkp-bmenu-marks-width))
+              (save-excursion
+                (let ((inhibit-read-only  t))
+                  (while bookmark-bmenu-hidden-bookmarks
+                    (move-to-column bmkp-bmenu-marks-width t)
+                    (bookmark-kill-line)
+                    (let ((name   (car bookmark-bmenu-hidden-bookmarks))
+                          (start  (point))
+                          end)
+                      (insert name)
+                      (move-to-column max-width t)
+                      (setq end  (point))
+                      (bmkp-bmenu-propertize-item name start end))
+                    (setq bookmark-bmenu-hidden-bookmarks  (cdr bookmark-bmenu-hidden-bookmarks))
+                    (forward-line 1))))))))
+    (unless no-msg-p (message "Hiding file names...done"))
+    (when (and (fboundp 'fit-frame-if-one-window)
+               (eq (selected-window) (get-buffer-window (get-buffer-create bmkp-bmenu-buffer) 0)))
+      (fit-frame-if-one-window))))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Prefix arg reverses `bmkp-use-region'.
+;; 2. Raise error if not in buffer `*Bookmark List*'.
+;;
+;;;###autoload (autoload 'bookmark-bmenu-1-window "bookmark+")
+(defun bookmark-bmenu-1-window (&optional flip-use-region-p) ; Bound to `1' in bookmark list
+  "Select this line's bookmark, alone, in full frame.
+See `bookmark-jump' for info about the prefix arg."
+  (interactive "P")
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bookmark-bmenu-ensure-position)
+  (bmkp-jump-1 (bookmark-bmenu-bookmark) 'pop-to-buffer flip-use-region-p)
+  (bury-buffer (other-buffer))
+  (delete-other-windows))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Prefix arg reverses `bmkp-use-region'.
+;; 2. Raise error if not in buffer `*Bookmark List*'.
+;;
+;;;###autoload (autoload 'bookmark-bmenu-2-window "bookmark+")
+(defun bookmark-bmenu-2-window (&optional flip-use-region-p) ; Bound to `2' in bookmark list
+  "Select this line's bookmark, with previous buffer in second window.
+See `bookmark-jump' for info about the prefix arg."
+  (interactive "P")
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bookmark-bmenu-ensure-position)
+  (let ((bookmark-name   (bookmark-bmenu-bookmark))
+        (menu            (current-buffer))
+        (pop-up-windows  t))
+    (delete-other-windows)
+    (bmkp--pop-to-buffer-same-window (other-buffer))
+    ;; (let ((bookmark-automatically-show-annotations nil)) ; $$$$$$ Needed?
+    (bmkp-jump-1 bookmark-name 'pop-to-buffer flip-use-region-p)
+    (bury-buffer menu)))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Prefix arg reverses `bmkp-use-region'.
+;; 2. Raise error if not in buffer `*Bookmark List*'.
+;;
+;;;###autoload (autoload 'bookmark-bmenu-this-window "bookmark+")
+(defun bookmark-bmenu-this-window (&optional flip-use-region-p) ; Bound to `RET' in bookmark list
+  "Select this line's bookmark in this window.
+See `bookmark-jump' for info about the prefix arg."
+  (interactive "P")
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bookmark-bmenu-ensure-position)
+  (let ((bookmark-name  (bookmark-bmenu-bookmark)))
+    (bmkp-jump-1 bookmark-name 'bmkp--pop-to-buffer-same-window flip-use-region-p)))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Use `pop-to-buffer', not `switch-to-buffer-other-window'.
+;; 2. Prefix arg reverses `bmkp-use-region'.
+;; 3. Raise error if not in buffer `*Bookmark List*'.
+;;
+;;;###autoload (autoload 'bookmark-bmenu-other-window "bookmark+")
+(defun bookmark-bmenu-other-window (&optional flip-use-region-p) ; Bound to `o' in bookmark list
+  "Select this line's bookmark in other window.  Show `*Bookmark List*' still.
+See `bookmark-jump' for info about the prefix arg."
+  (interactive "P")
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bookmark-bmenu-ensure-position)
+  (let ((bookmark-name  (bookmark-bmenu-bookmark)))
+    ;; (bookmark-automatically-show-annotations  t)) ; $$$$$$ Needed?
+    (bookmark-jump-other-window bookmark-name flip-use-region-p)))
+
+
+;; REPLACES ORIGINAL in `bookmark.el' (Emacs 27+).
+;;
+;; 1. Use `pop-to-buffer', not `view-buffer-other-frame'.
+;; 2. Prefix arg reverses `bmkp-use-region'.
+;; 3. Raise error if not in buffer `*Bookmark List*'.
+;;
+;;;###autoload (autoload 'bookmark-bmenu-other-window "bookmark+")
+(defun bookmark-bmenu-other-frame (&optional flip-use-region-p) ; Bound to `j 5' in bookmark list
+  "Select this line's bookmark in another frame.
+See `bookmark-jump' for info about the prefix arg."
+  (interactive "P")
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bookmark-bmenu-ensure-position)
+  (let ((bookmark-name  (bookmark-bmenu-bookmark)))
+    ;; (bookmark-automatically-show-annotations  t)) ; $$$$$$ Needed?
+    (bookmark-jump-other-frame bookmark-name flip-use-region-p)))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Prefix arg reverses `bmkp-use-region'.
+;; 2. Raise error if not in buffer `*Bookmark List*'.
+;;
+;;;###autoload (autoload 'bookmark-bmenu-switch-other-window "bookmark+")
+(defun bookmark-bmenu-switch-other-window (&optional flip-use-region-p) ; Bound to `C-o' in bookmark list
+  "Make the other window select this line's bookmark.
+The current window remains selected.
+See `bookmark-jump' for info about the prefix arg."
+  (interactive "P")
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bookmark-bmenu-ensure-position)
+  (let ((bookmark-name             (bookmark-bmenu-bookmark))
+        (pop-up-windows            t)
+        (same-window-buffer-names  ())
+        (same-window-regexps       ()))
+    ;; (bookmark-automatically-show-annotations t)) ; $$$$$$ Needed?
+    (bmkp-jump-1 bookmark-name 'display-buffer flip-use-region-p)))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Prefix arg reverses `bmkp-use-region'.
+;; 2. Raise error if not in buffer `*Bookmark List*'.
+;;
+;;;###autoload (autoload 'bookmark-bmenu-other-window-with-mouse "bookmark+")
+(defun bookmark-bmenu-other-window-with-mouse (event &optional flip-use-region-p)
+  "Select clicked bookmark in other window.  Show `*Bookmark List*' still.
+See `bookmark-jump' for info about the prefix arg."
+  (interactive "e\nP")
+  (with-current-buffer (window-buffer (posn-window (event-end event)))
+    (save-excursion (goto-char (posn-point (event-end event)))
+                    (bookmark-bmenu-other-window flip-use-region-p))))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Added optional arg MSG-P.
+;; 2. Call `bookmark-show-annotation' with arg MSG-P.
+;; 3. Raise error if not in buffer `*Bookmark List*'.
+;; 4. Doc string reflects enhanced behavior of `bookmark-show-annotation'.
+;;
+;;;###autoload (autoload 'bookmark-bmenu-show-annotation "bookmark+")
+(defun bookmark-bmenu-show-annotation (&optional msg-p) ; Bound to `a a' in bookmark list
+  "Show the annotation for the current bookmark, or follow it if external.
+If the annotation is external then jump to its destination.
+Non-interactively, non-nil MSG-P means display messages."
+  (interactive "p")
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bookmark-bmenu-ensure-position)
+  (let ((bmk  (bookmark-bmenu-bookmark)))
+    (unless bmk (error "No bookmark here"))
+    (bookmark-show-annotation bmk msg-p)))
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;;  1. Added optional arg MARKEDP: handle bookmarks marked `>', not just those flagged `D'.
+;;  2. Added optional arg NO-CONFIRM-P.
+;;  3. Delete bookmark on current line (after confirmation) if none are flagged/marked.
+;;  4. Inhibit saving until all are deleted, then save all.  This is because the Bookmark+ version of
+;;     `bookmark-save' refreshes the bookmark list display, and that removes `D' flags.
+;;  5. Use `bmkp-get-bookmark' instead of `bookmark-get-bookmark', so we can get the right bookmarks when
+;;     they have names with property `bmkp-full-record'.  But don't require that they have names, so
+;;     calls from vanilla or other code won't be bothered.
+;;  6. Use `bookmark-bmenu-surreptitiously-rebuild-list', instead of using
+;;     `bookmark-bmenu-list', updating the modification count, and saving.
+;;  7. Update `bmkp-latest-bookmark-alist' to reflect the deletions.
+;;  8. Pass full bookmark, not name, to `delete' (and do not use `assoc').
+;;  9. Use `bmkp-bmenu-goto-bookmark-named'.
+;; 10. Added status messages.
+;; 11. Raise error if not in buffer `*Bookmark List*'.
+;;
+;;;###autoload (autoload 'bookmark-bmenu-execute-deletions "bookmark+")
+(defun bookmark-bmenu-execute-deletions (&optional markedp no-confirm-p) ; Bound to `x' in bookmark list
+  "Delete (visible) bookmarks flagged `D', without confirmation.
+With a prefix argument, delete the bookmarks marked `>' instead, but
+only after confirmation.
+
+If NO bookmarks are flagged or marked (depending on whether a prefix
+arg was used), then delete the bookmark on this line, but only after
+confirmation.
+
+Non-interactively, optional arg NO-CONFIRM-P non-nil means do not ask
+for confirmation."
+  (interactive "P")
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (if (and (null (if markedp bmkp-bmenu-marked-bookmarks bmkp-flagged-bookmarks))
+           (bookmark-bmenu-bookmark))
+      (if (progn (let ((visible-bell                  t)
+                       (minibuffer-prompt-properties  (append minibuffer-prompt-properties
+                                                              '(face bmkp-*-mark))))
+                   (ding) (ding)
+                   (yes-or-no-p "DELETE THIS bookmark ")))
+          (bookmark-delete (bookmark-bmenu-bookmark))
+        (message "OK, not deleted"))
+    (if (or (not markedp)
+            no-confirm-p
+            (yes-or-no-p "Delete bookmarks marked `>' (not `D') "))
+        (let* ((mark-type  (if markedp "^>" "^D"))
+               (o-str      (and (not (bmkp-looking-at-p mark-type))  (bookmark-bmenu-bookmark)))
+               (o-point    (point))
+               (count      0))
+          (message "Deleting bookmarks...")
+          (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines)
+          (while (re-search-forward mark-type (point-max) t)
+            (let* ((bmk-name  (bookmark-bmenu-bookmark))
+                   (bmk       (bmkp-get-bookmark bmk-name nil 'NO-NAME-CHECK-P)))
+              ;; Inhibit saving until all are deleted, then do it once.  Otherwise, some might not be
+              ;; deleted, because `bookmark-save' refreshes the list, which removes `D' flags.
+              (let ((bookmark-save-flag  nil))  (bookmark-delete bmk-name 'BATCHP))
+              ;; Count is misleading if the bookmark is not really in `bookmark-alist'.
+              (setq count                       (1+ count)
+                    bmkp-latest-bookmark-alist  (delete bmk bmkp-latest-bookmark-alist))))
+          (bmkp-maybe-save-bookmarks)   ; Do it now.
+          (if (<= count 0)
+              (message (if markedp "No marked bookmarks" "No bookmarks flagged for deletion"))
+            (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P)
+            (message "Deleted %d bookmarks" count))
+          (if o-str
+              (bmkp-bmenu-goto-bookmark-named o-str)
+            (goto-char o-point)
+            (beginning-of-line)))
+      (message "OK, nothing deleted"))))
+
+
+
+;; REPLACES ORIGINAL in `bookmark.el'.
+;;
+;; 1. Do not call `bookmark-bmenu-list' (it was already called).
+;; 2. Raise error if not in buffer `*Bookmark List*'.
+;; 3. Use `bmkp-bmenu-goto-bookmark-named' instead of just searching for name.
+;;
+;;;###autoload (autoload 'bookmark-bmenu-rename "bookmark+")
+(defun bookmark-bmenu-rename ()         ; Bound to `r' in bookmark list
+  "Rename bookmark on current line.  Prompts for a new name."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bookmark-bmenu-ensure-position)
+  (let ((newname  (bookmark-rename (bookmark-bmenu-bookmark)))) (bmkp-bmenu-goto-bookmark-named newname)))
+ 
+;;(@* "Bookmark+ Functions (`bmkp-*')")
+;;; Bookmark+ Functions (`bmkp-*') -----------------------------------
+
+
+;;(@* "Menu-List (`*-bmenu-*') Filter Commands")
+;;  *** Menu-List (`*-bmenu-*') Filter Commands ***
+
+;; `bmkp-bmenu-show-only-autonamed-bookmarks',
+;; `bmkp-bmenu-show-only-non-file-bookmarks',
+;; `bmkp-bmenu-show-only-dired-bookmarks',
+;; `bmkp-bmenu-show-only-eww-bookmarks' (Emacs 25+),
+;; `bmkp-bmenu-show-only-function-bookmarks',
+;; `bmkp-bmenu-show-only-gnus-bookmarks',
+;; `bmkp-bmenu-show-only-icicles-search-hits-bookmarks',
+;; `bmkp-bmenu-show-only-non-invokable-bookmarks',
+;; `bmkp-bmenu-show-only-image-bookmarks',
+;; `bmkp-bmenu-show-only-info-bookmarks',
+;; `bmkp-bmenu-show-only-desktop-bookmarks',
+;; `bmkp-bmenu-show-only-man-bookmarks',
+;; `bmkp-bmenu-show-only-region-bookmarks',
+;; `bmkp-bmenu-show-only-tagged-bookmarks',
+;; `bmkp-bmenu-show-only-untagged-bookmarks',
+;; `bmkp-bmenu-show-only-url-bookmarks',
+;; `bmkp-bmenu-show-only-variable-list-bookmarks',
+;; `bmkp-bmenu-show-only-snippet-bookmarks',
+;; `bmkp-bmenu-show-only-w3m-bookmarks',
+;; `bmkp-bmenu-show-only-temporary-bookmarks',
+;; `bmkp-bmenu-show-only-bookmark-file-bookmarks',
+;; `bmkp-bmenu-show-only-bookmark-list-bookmarks',
+
+
+;; The simple ones are defined using macro `bmkp-define-show-only-command'.
+;;
+;;;###autoload (autoload 'bmkp-bmenu-show-only-autonamed-bookmarks "bookmark+")
+;;;###autoload (autoload 'bmkp-bmenu-show-only-non-file-bookmarks "bookmark+")
+;;;###autoload (autoload 'bmkp-bmenu-show-only-dired-bookmarks "bookmark+")
+
+;; ;;;###autoload (autoload 'bmkp-bmenu-show-only-eww-bookmarks "bookmark+")
+
+;;;###autoload (autoload 'bmkp-bmenu-show-only-function-bookmarks "bookmark+")
+;;;###autoload (autoload 'bmkp-bmenu-show-only-gnus-bookmarks "bookmark+")
+;;;###autoload (autoload 'bmkp-bmenu-show-only-icicles-search-hits-bookmarks "bookmark+")
+;;;###autoload (autoload 'bmkp-bmenu-show-only-non-invokable-bookmarks "bookmark+")
+;;;###autoload (autoload 'bmkp-bmenu-show-only-image-bookmarks "bookmark+")
+;;;###autoload (autoload 'bmkp-bmenu-show-only-info-bookmarks "bookmark+")
+;;;###autoload (autoload 'bmkp-bmenu-show-only-desktop-bookmarks "bookmark+")
+;;;###autoload (autoload 'bmkp-bmenu-show-only-man-bookmarks "bookmark+")
+;;;###autoload (autoload 'bmkp-bmenu-show-only-region-bookmarks "bookmark+")
+;;;###autoload (autoload 'bmkp-bmenu-show-only-tagged-bookmarks "bookmark+")
+;;;###autoload (autoload 'bmkp-bmenu-show-only-untagged-bookmarks "bookmark+")
+;;;###autoload (autoload 'bmkp-bmenu-show-only-url-bookmarks "bookmark+")
+;;;###autoload (autoload 'bmkp-bmenu-show-only-variable-list-bookmarks "bookmark+")
+;;;###autoload (autoload 'bmkp-bmenu-show-only-snippet-bookmarks "bookmark+")
+;;;###autoload (autoload 'bmkp-bmenu-show-only-w3m-bookmarks "bookmark+")
+;;;###autoload (autoload 'bmkp-bmenu-show-only-temporary-bookmarks "bookmark+")
+;;;###autoload (autoload 'bmkp-bmenu-show-only-bookmark-file-bookmarks "bookmark+")
+;;;###autoload (autoload 'bmkp-bmenu-show-only-bookmark-list-bookmarks "bookmark+")
+
+;; Bindings indicated are in `*Bookmark List*'.
+(bmkp-define-show-only-command autonamed "Display (only) the autonamed bookmarks."
+                               bmkp-autonamed-alist-only)                                     ; `# S'
+(bmkp-define-show-only-command non-file "Display (only) the non-file (buffer) bookmarks."
+                               bmkp-non-file-alist-only)                                      ; `B S'
+(bmkp-define-show-only-command dired "Display (only) the Dired bookmarks."
+                               bmkp-dired-alist-only)                                         ; `M-d M-s'
+(bmkp-define-show-only-command gnus "Display (only) the gnus bookmarks."
+                               bmkp-gnus-alist-only)                                          ; `G S'
+(bmkp-define-show-only-command "icicles search-hits" "Display (only) the Icicles search-hits bookmarks."
+                               bmkp-icicles-search-hits-alist-only)                           ; `i S'
+(bmkp-define-show-only-command image "Display (only) the image-file bookmarks."
+                               bmkp-image-alist-only)                                         ; `M-I M-S'
+(bmkp-define-show-only-command info "Display (only) the Info bookmarks."
+                               bmkp-info-alist-only)                                          ; `I S'
+(bmkp-define-show-only-command desktop  "Display (only) the desktop bookmarks."
+                               bmkp-desktop-alist-only)                                       ; `K S'
+(bmkp-define-show-only-command man-page "Display (only) the `man' page bookmarks."
+                               bmkp-man-alist-only)                                           ; `M S'
+(bmkp-define-show-only-command function "Display (only) the function bookmarks."
+                               bmkp-function-alist-only)                                      ; `Q S'
+(bmkp-define-show-only-command region "Display (only) the bookmarks that record a region."
+                               bmkp-region-alist-only)                                        ; `R S'
+(bmkp-define-show-only-command tagged "Display (only) the bookmarks that have tags."
+                               bmkp-tagged-alist-only)                                        ; `T S'
+(bmkp-define-show-only-command untagged "Display (only) the bookmarks that do not have tags."
+                               bmkp-untagged-alist-only)                                      ; Not bound
+(bmkp-define-show-only-command url "Display (only) the url bookmarks."
+                               bmkp-url-alist-only)                                           ; `M-u M-s'
+(bmkp-define-show-only-command variable-list "Display (only) the variable-list bookmarks."
+                               bmkp-variable-list-alist-only)                                 ; `V S'
+(bmkp-define-show-only-command snippet "Display (only) the snippet bookmarks."
+                               bmkp-snippet-alist-only)                                       ; `w S'
+(when (fboundp 'bmkp-eww-bookmark-p)    ; Emacs 25+
+  (bmkp-define-show-only-command eww "Display (only) the EWW URL bookmarks."
+                                 bmkp-eww-alist-only))                                        ; `W E S'
+(bmkp-define-show-only-command w3m "Display (only) the W3M URL bookmarks."
+                               bmkp-w3m-alist-only)                                           ; `W 3 S'
+(bmkp-define-show-only-command temporary "Display (only) the temporary bookmarks."
+                               bmkp-temporary-alist-only)                                     ; `X S'
+(bmkp-define-show-only-command bookmark-file "Display (only) the bookmark-file bookmarks."
+                               bmkp-bookmark-file-alist-only)                                 ; `Y S'
+(bmkp-define-show-only-command bookmark-list  "Display (only) the bookmark-list bookmarks."
+                               bmkp-bookmark-list-alist-only)                                 ; `Z S'
+
+;;;###autoload (autoload 'bmkp-bmenu-show-all "bookmark+")
+(defun bmkp-bmenu-show-all ()           ; Bound to `.' in bookmark list
+  "Show all bookmarks known to the bookmark list (aka \"menu list\").
+Omitted bookmarks are not shown, however.
+Also, this does not revert the bookmark list, to bring it up to date.
+To revert the display from the current list, use `\\<bookmark-bmenu-mode-map>\
+\\[bmkp-bmenu-refresh-menu-list]'.
+To revert the list and display from the bookmark file, use `C-u \\[bmkp-bmenu-refresh-menu-list]'."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (setq bmkp-bmenu-filter-function  nil
+        bmkp-bmenu-title            "All Bookmarks"
+        bmkp-latest-bookmark-alist  bookmark-alist)
+  (bookmark-bmenu-list)
+  (when (interactive-p) (bmkp-msg-about-sort-order (bmkp-current-sort-order) "All bookmarks are shown")))
+
+;;;###autoload (autoload 'bmkp-bmenu-show-only-autofile-bookmarks "bookmark+")
+(defun bmkp-bmenu-show-only-autofile-bookmarks (&optional arg) ; Bound to `A S' in bookmark list
+  "Display (only) the autofile bookmarks.
+This means bookmarks whose names are the same as the nondirectory part
+of their file names (or their `directory-file-name', for directories).
+
+But with a prefix arg you are prompted for a prefix that each bookmark
+name must have."
+  (interactive "P")
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (setq bmkp-bmenu-filter-function  (if (not arg)
+                                        'bmkp-autofile-alist-only
+                                      (let ((prefix  (read-string "Prefix for bookmark names: "
+                                                                  nil nil "")))
+                                        `(lambda () (bmkp-autofile-alist-only ,prefix))))
+        bmkp-bmenu-title            "Autofile Bookmarks")
+  (let ((bookmark-alist  (funcall bmkp-bmenu-filter-function)))
+    (setq bmkp-latest-bookmark-alist  bookmark-alist)
+    (bookmark-bmenu-list 'filteredp))
+  (when (interactive-p)
+    (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only autofile bookmarks are shown")))
+
+;;;###autoload (autoload 'bmkp-bmenu-show-only-file-bookmarks "bookmark+")
+(defun bmkp-bmenu-show-only-file-bookmarks (&optional arg) ; Bound to `F S' in bookmark list
+  "Display a list of file and directory bookmarks (only).
+With a prefix argument, do not include remote files or directories."
+  (interactive "P")
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (setq bmkp-bmenu-filter-function  (if arg 'bmkp-local-file-alist-only 'bmkp-file-alist-only)
+        bmkp-bmenu-title            (if arg
+                                        "Local File and Directory Bookmarks"
+                                      "File and Directory Bookmarks"))
+  (let ((bookmark-alist  (funcall bmkp-bmenu-filter-function)))
+    (setq bmkp-latest-bookmark-alist  bookmark-alist)
+    (bookmark-bmenu-list 'filteredp))
+  (when (interactive-p)
+    (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only file bookmarks are shown")))
+
+;;;###autoload (autoload 'bmkp-bmenu-show-only-orphaned-local-file-bookmarks "bookmark+")
+(defun bmkp-bmenu-show-only-orphaned-local-file-bookmarks (&optional arg) ; `O S' in bookmark list
+  "Display a list of orphaned local file and directory bookmarks (only).
+With a prefix argument, include remote orphans as well."
+  (interactive "P")
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (setq bmkp-bmenu-filter-function  (if arg
+                                        'bmkp-orphaned-file-alist-only
+                                      'bmkp-orphaned-local-file-alist-only)
+        bmkp-bmenu-title            (if arg
+                                        "Orphaned File and Directory Bookmarks"
+                                      "Local Orphaned File and Directory Bookmarks"))
+  (let ((bookmark-alist  (funcall bmkp-bmenu-filter-function)))
+    (setq bmkp-latest-bookmark-alist  bookmark-alist)
+    (bookmark-bmenu-list 'filteredp))
+  (when (interactive-p)
+    (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only orphaned file bookmarks are shown")))
+
+;;;###autoload (autoload 'bmkp-bmenu-show-only-specific-buffer-bookmarks "bookmark+")
+(defun bmkp-bmenu-show-only-specific-buffer-bookmarks (&optional buffer) ; `= b S' in bookmark list
+  "Display (only) the bookmarks for BUFFER.
+Interactively, read the BUFFER name.
+If BUFFER is non-nil, set `bmkp-last-specific-buffer' to it."
+  (interactive (list (bmkp-completing-read-buffer-name)))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (when buffer (setq bmkp-last-specific-buffer  buffer))
+  (setq bmkp-bmenu-filter-function  'bmkp-last-specific-buffer-alist-only
+        bmkp-bmenu-title            (format "Buffer `%s' Bookmarks" bmkp-last-specific-buffer))
+  (let ((bookmark-alist  (funcall bmkp-bmenu-filter-function)))
+    (setq bmkp-latest-bookmark-alist  bookmark-alist)
+    (bookmark-bmenu-list 'filteredp))
+  (when (interactive-p)
+    (bmkp-msg-about-sort-order (bmkp-current-sort-order)
+                               (format "Only bookmarks for buffer `%s' are shown"
+                                       bmkp-last-specific-buffer))))
+
+;;;###autoload (autoload 'bmkp-bmenu-show-only-specific-file-bookmarks "bookmark+")
+(defun bmkp-bmenu-show-only-specific-file-bookmarks (&optional file) ; Bound to `= f S' in bookmark list
+  "Display (only) the bookmarks for FILE, an absolute file name.
+Interactively, read the FILE name.
+If FILE is non-nil, set `bmkp-last-specific-file' to it."
+  (interactive (list (bmkp-completing-read-file-name)))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (let ((orig-last-spec-file  bmkp-last-specific-file)
+        (orig-filter-fn       bmkp-bmenu-filter-function)
+        (orig-title           bmkp-bmenu-title)
+        (orig-latest-alist    bmkp-latest-bookmark-alist))
+    (condition-case err
+        (progn
+          (when file (setq bmkp-last-specific-file  file))
+          (setq bmkp-bmenu-filter-function  'bmkp-last-specific-file-alist-only
+                bmkp-bmenu-title            (format "File `%s' Bookmarks" bmkp-last-specific-file))
+          (let ((bookmark-alist         (funcall bmkp-bmenu-filter-function))
+                (bmkp-bmenu-state-file  nil)) ; Prevent restoring saved state.
+            (setq bmkp-latest-bookmark-alist  bookmark-alist)
+            (bookmark-bmenu-list 'filteredp))
+          (when (interactive-p)
+            (bmkp-msg-about-sort-order (bmkp-current-sort-order)
+                                       (format "Only bookmarks for file `%s' are shown"
+                                               bmkp-last-specific-file)))
+          (raise-frame))
+      (error (progn (setq bmkp-last-specific-file     orig-last-spec-file
+                          bmkp-bmenu-filter-function  orig-filter-fn
+                          bmkp-bmenu-title            orig-title
+                          bmkp-latest-bookmark-alist  orig-latest-alist)
+                    (error "%s" (error-message-string err)))))))
+
+
+;;;###autoload (autoload 'bmkp-bmenu-refresh-menu-list "bookmark+")
+(defun bmkp-bmenu-refresh-menu-list (&optional parg msg-p) ; Bound to `g' in bookmark list
+  "Refresh (revert) the bookmark list display (aka \"menu list\").
+This brings the displayed list up to date with respect to the current
+bookmark list.  It does not change the filtering or sorting of the
+displayed list.
+
+With a prefix argument and upon confirmation, refresh the bookmark
+list and its display from the current bookmark file.  IOW, it reloads
+the file, overwriting the current bookmark list.  This also removes
+any markings and omissions.
+
+You can use command `bmkp-toggle-bookmark-set-refreshes' to toggle
+whether setting a bookmark in any way should automatically refresh the
+list.
+
+From Lisp, non-nil optional arg MSG-P means show progress messages."
+  (interactive "P\np")
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (let ((msg  "Refreshing from bookmark "))
+    (cond ((and parg  (yes-or-no-p (format "Refresh list to bookmarks saved in file `%s'? "
+                                           bmkp-current-bookmark-file)))
+           (when msg-p (message (setq msg  (concat msg "file..."))))
+           (bookmark-load bmkp-current-bookmark-file 'OVERWRITE 'BATCH-NO-SAVE)
+           (setq bmkp-bmenu-marked-bookmarks   () ; Start from scratch.
+                 bmkp-modified-bookmarks       ()
+                 bmkp-flagged-bookmarks        ()
+                 bmkp-bmenu-omitted-bookmarks  (condition-case nil
+                                                   (eval (car (get 'bmkp-bmenu-omitted-bookmarks
+                                                                   'saved-value)))
+                                                 (error nil)))
+           (let ((bmkp-bmenu-filter-function  nil)) ; Remove any filtering.
+             (bmkp-refresh-menu-list (bookmark-bmenu-bookmark) (not msg-p))))
+          (t
+           (when msg-p (message (setq msg  (concat msg "list in memory..."))))
+           (bmkp-refresh-menu-list (bookmark-bmenu-bookmark) (not msg-p))))
+    (when msg-p (message (concat msg "done")))))
+
+;;;###autoload (autoload 'bmkp-bmenu-filter-bookmark-name-incrementally "bookmark+")
+(defun bmkp-bmenu-filter-bookmark-name-incrementally () ; Bound to `P B' in bookmark list
+  "Incrementally filter bookmarks by bookmark name using a regexp."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (unwind-protect
+      (progn (setq bmkp-bmenu-filter-timer
+                   (run-with-idle-timer bmkp-incremental-filter-delay 'REPEAT
+                                        #'bmkp-bmenu-filter-alist-by-bookmark-name-regexp))
+             (bmkp-bmenu-read-filter-input))
+    (bmkp-bmenu-cancel-incremental-filtering)))
+
+(defun bmkp-bmenu-filter-alist-by-bookmark-name-regexp ()
+  "Filter bookmarks by bookmark name, then refresh the bookmark list."
+  (setq bmkp-bmenu-filter-function  'bmkp-regexp-filtered-bookmark-name-alist-only
+        bmkp-bmenu-title            (format "Bookmarks with Names Matching Regexp `%s'"
+                                            bmkp-bmenu-filter-pattern))
+  (let ((bookmark-alist  (funcall bmkp-bmenu-filter-function)))
+    (setq bmkp-latest-bookmark-alist  bookmark-alist)
+    (bookmark-bmenu-list 'filteredp)))
+
+;;;###autoload (autoload 'bmkp-bmenu-filter-file-name-incrementally "bookmark+")
+(defun bmkp-bmenu-filter-file-name-incrementally () ; Bound to `P F' in bookmark list
+  "Incrementally filter bookmarks by file name using a regexp."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (unwind-protect
+      (progn (setq bmkp-bmenu-filter-timer
+                   (run-with-idle-timer bmkp-incremental-filter-delay 'REPEAT
+                                        #'bmkp-bmenu-filter-alist-by-file-name-regexp))
+             (bmkp-bmenu-read-filter-input))
+    (bmkp-bmenu-cancel-incremental-filtering)))
+
+(defun bmkp-bmenu-filter-alist-by-file-name-regexp ()
+  "Filter bookmarks by file name, then refresh the bookmark list."
+  (setq bmkp-bmenu-filter-function  'bmkp-regexp-filtered-file-name-alist-only
+        bmkp-bmenu-title            (format "Bookmarks with File Names Matching Regexp `%s'"
+                                            bmkp-bmenu-filter-pattern))
+  (let ((bookmark-alist  (funcall bmkp-bmenu-filter-function)))
+    (setq bmkp-latest-bookmark-alist  bookmark-alist)
+    (bookmark-bmenu-list 'filteredp)))
+
+;;;###autoload (autoload 'bmkp-bmenu-filter-annotation-incrementally "bookmark+")
+(defun bmkp-bmenu-filter-annotation-incrementally () ; Bound to `P A' in bookmark list
+  "Incrementally filter bookmarks by their annotations using a regexp."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (unwind-protect
+      (progn (setq bmkp-bmenu-filter-timer
+                   (run-with-idle-timer bmkp-incremental-filter-delay 'REPEAT
+                                        #'bmkp-bmenu-filter-alist-by-annotation-regexp))
+             (bmkp-bmenu-read-filter-input))
+    (bmkp-bmenu-cancel-incremental-filtering)))
+
+(defun bmkp-bmenu-filter-alist-by-annotation-regexp ()
+  "Filter bookmarks by annoation, then refresh the bookmark list."
+  (setq bmkp-bmenu-filter-function  'bmkp-regexp-filtered-annotation-alist-only
+        bmkp-bmenu-title            (format "Bookmarks with Annotations Matching Regexp `%s'"
+                                            bmkp-bmenu-filter-pattern))
+  (let ((bookmark-alist  (funcall bmkp-bmenu-filter-function)))
+    (setq bmkp-latest-bookmark-alist  bookmark-alist)
+    (bookmark-bmenu-list 'filteredp)))
+
+;;;###autoload (autoload 'bmkp-bmenu-filter-tags-incrementally "bookmark+")
+(defun bmkp-bmenu-filter-tags-incrementally () ; Bound to `P T' in bookmark list
+  "Incrementally filter bookmarks by tags using a regexp."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (unwind-protect
+      (progn (setq bmkp-bmenu-filter-timer
+                   (run-with-idle-timer bmkp-incremental-filter-delay 'REPEAT
+                                        #'bmkp-bmenu-filter-alist-by-tags-regexp))
+             (bmkp-bmenu-read-filter-input))
+    (bmkp-bmenu-cancel-incremental-filtering)))
+
+(defun bmkp-bmenu-filter-alist-by-tags-regexp ()
+  "Filter bookmarks by tags, then refresh the bookmark list."
+  (setq bmkp-bmenu-filter-function  'bmkp-regexp-filtered-tags-alist-only
+        bmkp-bmenu-title            (format "Bookmarks with Tags Matching Regexp `%s'"
+                                            bmkp-bmenu-filter-pattern))
+  (let ((bookmark-alist  (funcall bmkp-bmenu-filter-function)))
+    (setq bmkp-latest-bookmark-alist  bookmark-alist)
+    (bookmark-bmenu-list 'filteredp)))
+
+(defun bmkp-bmenu-read-filter-input ()
+  "Read input and add it to `bmkp-bmenu-filter-pattern'."
+  (setq bmkp-bmenu-filter-pattern  "")
+  (let ((curr-bmk       (bookmark-bmenu-bookmark))
+        (orig-title     bmkp-bmenu-title)
+        (orig-filt-fn   bmkp-bmenu-filter-function)
+        (orig-filt-pat  bmkp-bmenu-filter-pattern))
+    (when (eq 'QUIT
+              (let ((tmp-list                                  ())
+                    (inhibit-quit                              t)
+                    (prefix-command-echo-keystrokes-functions  ()) ; 25+  See Emacs bug #44500.
+                    char)
+                (catch 'bmkp-bmenu-read-filter-input
+                  (while (condition-case nil
+                             (setq char  (read-char (concat "Pattern: " bmkp-bmenu-filter-pattern)))
+                           ;; `read-char' raises an error for non-char event.
+                           (error (throw 'bmkp-bmenu-read-filter-input nil)))
+                    (unless (or (not (fboundp 'characterp))  (characterp char)) ; E.g. `M-x', `M-:'
+                      (throw 'bmkp-bmenu-read-filter-input nil))
+                    (case char
+                      ((?\e ?\r)  (throw 'bmkp-bmenu-read-filter-input nil)) ; Break and exit.
+                      (?\C-g      (setq inhibit-quit  nil)
+                                  (throw 'bmkp-bmenu-read-filter-input 'QUIT)) ; Quit.
+                      (?\d        (or (null tmp-list) ; No-op if no chars to delete.
+                                      (pop tmp-list)
+                                      t)) ; Delete last char of `bmkp-bmenu-filter-pattern'.
+                      (t          (push (text-char-description char) tmp-list))) ; Accumulate CHAR.
+                    (setq bmkp-bmenu-filter-pattern  (mapconcat #'identity (reverse tmp-list) ""))))))
+      (message "Restoring display prior to incremental filtering...")
+      (setq bmkp-bmenu-title            orig-title
+            bmkp-bmenu-filter-function  orig-filt-fn
+            bmkp-bmenu-filter-pattern   orig-filt-pat)
+      (bookmark-bmenu-list 'FILTEREDP)
+      (bmkp-bmenu-goto-bookmark-named curr-bmk)
+      (message "Restoring display prior to incremental filtering...done"))))
+
+(defun bmkp-bmenu-cancel-incremental-filtering ()
+  "Cancel timer used for incrementally filtering bookmarks."
+  (cancel-timer bmkp-bmenu-filter-timer)
+  (setq bmkp-bmenu-filter-timer  nil))
+
+;;;###autoload (autoload 'bmkp-bmenu-toggle-show-only-unmarked "bookmark+")
+(defun bmkp-bmenu-toggle-show-only-unmarked () ; Bound to `<' in bookmark list
+  "Hide all marked bookmarks.  Repeat to toggle, showing all."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  ;; Save display, to be sure `bmkp-bmenu-before-hide-marked-alist' is up-to-date.
+  (bmkp-save-menu-list-state)
+  (if (or (bmkp-some-marked-p bmkp-latest-bookmark-alist)
+          (bmkp-some-marked-p bmkp-bmenu-before-hide-marked-alist))
+      (let ((bookmark-alist  bmkp-latest-bookmark-alist)
+            status)
+        (if bmkp-bmenu-before-hide-marked-alist
+            (setq bookmark-alist                       bmkp-bmenu-before-hide-marked-alist
+                  bmkp-bmenu-before-hide-marked-alist  ()
+                  bmkp-latest-bookmark-alist           bookmark-alist
+                  status                               'shown)
+          (setq bmkp-bmenu-before-hide-marked-alist  bmkp-latest-bookmark-alist
+                bookmark-alist                       (bmkp-unmarked-bookmarks-only)
+                bmkp-latest-bookmark-alist           bookmark-alist
+                status                               'hidden))
+        (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P)
+        (cond ((eq status 'hidden)
+               (bookmark-bmenu-ensure-position)
+               (message "Marked bookmarks are now hidden"))
+              (t
+               (goto-char (point-min))
+               (when (re-search-forward "^>" (point-max) t)  (forward-line 0))
+               (message "Marked bookmarks no longer hidden"))))
+    (message "No marked bookmarks to hide"))
+  (when (and (fboundp 'fit-frame-if-one-window)
+             (eq (selected-window) (get-buffer-window (get-buffer-create bmkp-bmenu-buffer) 0)))
+    (fit-frame-if-one-window)))
+
+;;;###autoload (autoload 'bmkp-bmenu-toggle-show-only-marked "bookmark+")
+(defun bmkp-bmenu-toggle-show-only-marked () ; Bound to `>' in bookmark list
+  "Hide all unmarked bookmarks.  Repeat to toggle, showing all."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  ;; Save display, to be sure `bmkp-bmenu-before-hide-unmarked-alist' is up-to-date.
+  (bmkp-save-menu-list-state)
+  (if (or (bmkp-some-unmarked-p bmkp-latest-bookmark-alist)
+          (bmkp-some-unmarked-p bmkp-bmenu-before-hide-unmarked-alist))
+      (let ((bookmark-alist  bmkp-latest-bookmark-alist)
+            status)
+        (if bmkp-bmenu-before-hide-unmarked-alist
+            (setq bookmark-alist                         bmkp-bmenu-before-hide-unmarked-alist
+                  bmkp-bmenu-before-hide-unmarked-alist  ()
+                  bmkp-latest-bookmark-alist             bookmark-alist
+                  status                                 'shown)
+          (setq bmkp-bmenu-before-hide-unmarked-alist  bmkp-latest-bookmark-alist
+                bookmark-alist                         (bmkp-marked-bookmarks-only)
+                bmkp-latest-bookmark-alist             bookmark-alist
+                status                                 'hidden))
+        (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P)
+        (cond ((eq status 'hidden)
+               (bookmark-bmenu-ensure-position)
+               (message "Unmarked bookmarks are now hidden"))
+              (t
+               (goto-char (point-min))
+               (when (re-search-forward "^>" (point-max) t)  (forward-line 0))
+               (message "Unmarked bookmarks no longer hidden"))))
+    (message "No unmarked bookmarks to hide"))
+  (when (and (fboundp 'fit-frame-if-one-window)
+             (eq (selected-window) (get-buffer-window (get-buffer-create bmkp-bmenu-buffer) 0)))
+    (fit-frame-if-one-window)))
+
+
+;;(@* "Menu-List (`*-bmenu-*') Commands Involving Marks")
+;;  *** Menu-List (`*-bmenu-*') Commands Involving Marks ***
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-all "bookmark+")
+(defun bmkp-bmenu-mark-all (&optional no-re-sort-p msg-p) ; Bound to `M-m' in bookmark list
+  "Mark all bookmarks, using mark `>'.
+If any bookmark was unmarked before, and if the sort order is marked
+first or last (`s >'), then re-sort.
+
+Non-interactively:
+* Non-nil optional arg NO-RE-SORT-P inhibits re-sorting.
+* Non-nil optional arg MSG-P means display a status message."
+  (interactive "i\np")
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (let ((count      0)
+        (nb-marked  (length bmkp-bmenu-marked-bookmarks)))
+    (save-excursion
+      (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines)
+      (when msg-p (message "Updating bookmark-list display..."))
+      (while (not (eobp)) (bookmark-bmenu-mark 'NO-RE-SORT-P) (setq count  (1+ count))))
+    (unless no-re-sort-p
+      ;; If some were unmarked before, and if sort order is `s >' then re-sort.
+      (when (and (/= nb-marked count)  (equal bmkp-sort-comparer '((bmkp-marked-cp) bmkp-alpha-p)))
+        (let ((curr-bmk  (bookmark-bmenu-bookmark)))
+          (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P)
+          (when curr-bmk (bmkp-bmenu-goto-bookmark-named curr-bmk)))))
+    (when msg-p (message "Marked: %d" count))))
+
+;; This is similar to `dired-unmark-all-files'.
+;;;###autoload (autoload 'bmkp-bmenu-unmark-all "bookmark+")
+(defun bmkp-bmenu-unmark-all (mark &optional arg no-re-sort-p msg-p) ; Bound to `M-DEL', `U' in bmk list
+  "Remove a mark from each bookmark.
+Hit the mark character (`>' or `D') to remove those marks,
+ or hit `RET' to remove all marks (both `>' and `D').
+With a prefix arg, you are queried to unmark each marked bookmark.
+Use `\\[help-command]' during querying for help.
+
+If any bookmark was marked before, and if the sort order is marked
+first or last (`s >'), then re-sort.
+
+Non-interactively:
+* MARK is the mark character or a carriage-return character (`?\r').
+* Non-nil ARG (prefix arg) means query.
+* Non-nil optional arg NO-RE-SORT-P inhibits re-sorting.
+* Non-nil optional arg MSG-P means display a status message."
+  (interactive "cRemove marks (RET means all): \nP\ni\np")
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (require 'dired-aux)
+  (let* ((count              0)
+         (some-marked-p      bmkp-bmenu-marked-bookmarks)
+         (inhibit-read-only  t)
+         (case-fold-search   nil)
+         (query              nil)
+         (string             (format "\n%c" mark))
+         (help-form          "Type SPC or `y' to unmark one bookmark, DEL or `n' to skip to next,
+`!' to unmark all remaining bookmarks with no more questions."))
+    (save-excursion
+      (goto-char (point-min))
+      (forward-line (if (eq mark ?\r)
+                        bmkp-bmenu-header-lines
+                      (1- bmkp-bmenu-header-lines))) ; Because STRING starts with a newline.
+      (while (and (not (eobp))
+                  (if (eq mark ?\r)
+                      (re-search-forward dired-re-mark nil t)
+                    (let ((case-fold-search  t)) ; Treat `d' the same as `D'.
+                      (search-forward string nil t))))
+        (when (or (prog1 (not arg) (when msg-p (message "Updating bookmark-list display...")))
+                  (let ((bmk  (bookmark-bmenu-bookmark)))
+                    (and bmk  (dired-query 'query "Unmark bookmark `%s'? " bmk))))
+          (bookmark-bmenu-unmark nil 'NO-RE-SORT-P) (forward-line -1)
+          (setq count  (1+ count)))))
+    (unless no-re-sort-p
+      ;; If some were marked before, and if sort order is `s >', then re-sort.
+      (when (and some-marked-p  (equal bmkp-sort-comparer '((bmkp-marked-cp) bmkp-alpha-p)))
+        (let ((curr-bmk  (bookmark-bmenu-bookmark)))
+          (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P)
+          (when curr-bmk (bmkp-bmenu-goto-bookmark-named curr-bmk)))))
+    (when msg-p (if (= 1 count) (message "1 mark removed") (message "%d marks removed" count)))))
+
+;;;###autoload (autoload 'bmkp-bmenu-regexp-mark "bookmark+")
+(defun bmkp-bmenu-regexp-mark (regexp &optional no-re-sort-p msg-p) ; Bound to `% m' in bookmark list
+  "Mark bookmarks that match REGEXP.
+The entire bookmark line is tested: bookmark name and possibly file name.
+Note too that if file names are not shown currently then the bookmark
+name is padded at the right with spaces.
+
+If any bookmark was unmarked before, and if the sort order is marked
+first or last (`s >'), then re-sort.
+
+Non-interactively:
+* Non-nil optional arg NO-RE-SORT-P inhibits re-sorting.
+* Non-nil optional arg MSG-P means display a status message."
+  (interactive (list (bmkp-read-regexp "Regexp: ") (prefix-numeric-value current-prefix-arg)))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (let ((count      0)
+        (nb-marked  (length bmkp-bmenu-marked-bookmarks)))
+    (save-excursion
+      (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines)
+      (when msg-p (message "Updating bookmark-list display..."))
+      (while (and (not (eobp))  (re-search-forward regexp (point-max) t))
+        (bookmark-bmenu-mark 'NO-RE-SORT-P)
+        (setq count  (1+ count))))
+    (unless no-re-sort-p
+      ;; If some were unmarked before, and if sort order is `s >', then re-sort.
+      (when (and (equal bmkp-sort-comparer '((bmkp-marked-cp) bmkp-alpha-p))
+                 (< nb-marked (length bmkp-bmenu-marked-bookmarks)))
+        (let ((curr-bmk  (bookmark-bmenu-bookmark)))
+          (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P)
+          (when curr-bmk (bmkp-bmenu-goto-bookmark-named curr-bmk)))))
+    (when msg-p (if (= 1 count) (message "1 bookmark matched") (message "%d bookmarks matched" count)))))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-autofile-bookmarks "bookmark+")
+(defun bmkp-bmenu-mark-autofile-bookmarks (&optional arg msgp) ; Bound to `A M' in bookmark list
+  "Mark autofile bookmarks: those whose names are the same as their files.
+With a prefix arg you are prompted for a prefix that each bookmark
+name must have."
+  (interactive "P\np")
+  (if (not arg)
+      (bmkp-bmenu-mark-bookmarks-satisfying #'bmkp-autofile-bookmark-p nil msgp)
+    (let ((prefix  (read-string "Prefix for bookmark names: " nil nil "")))
+      (bmkp-bmenu-mark-bookmarks-satisfying
+       #'(lambda (bb) (bmkp-autofile-bookmark-p bb prefix)) nil msgp))))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-autonamed-bookmarks "bookmark+")
+(defun bmkp-bmenu-mark-autonamed-bookmarks (&optional msgp) ; Bound to `# M' in bookmark list
+  "Mark autonamed bookmarks."
+  (interactive "p")
+  (bmkp-bmenu-mark-bookmarks-satisfying #'bmkp-autonamed-bookmark-p nil msgp))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-bookmark-file-bookmarks "bookmark+")
+(defun bmkp-bmenu-mark-bookmark-file-bookmarks (&optional msgp) ; Bound to `Y M' in bookmark list
+  "Mark bookmark-file bookmarks."
+  (interactive "p")
+  (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-bookmark-file-bookmark-p nil msgp))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-bookmark-list-bookmarks "bookmark+")
+(defun bmkp-bmenu-mark-bookmark-list-bookmarks (&optional msgp) ; Bound to `Z M' in bookmark list
+  "Mark bookmark-list bookmarks."
+  (interactive "p")
+  (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-bookmark-list-bookmark-p nil msgp))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-desktop-bookmarks "bookmark+")
+(defun bmkp-bmenu-mark-desktop-bookmarks (&optional msgp) ; Bound to `K M' in bookmark list
+  "Mark desktop bookmarks."
+  (interactive "p")
+  (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-desktop-bookmark-p nil msgp))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-dired-bookmarks "bookmark+")
+(defun bmkp-bmenu-mark-dired-bookmarks (&optional msgp) ; Bound to `M-d M-m' in bookmark list
+  "Mark Dired bookmarks."
+  (interactive "p")
+  (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-dired-bookmark-p nil msgp))
+
+(when (fboundp 'bmkp-eww-bookmark-p)    ; Emacs 25+
+
+  ;; ;;;###autoload (autoload 'bmkp-bmenu-mark-eww-bookmarks "bookmark+")
+  (defun bmkp-bmenu-mark-eww-bookmarks (&optional msgp) ; Bound to `W E M' in bookmark list
+    "Mark EWW (URL) bookmarks."
+    (interactive "p")
+    (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-eww-bookmark-p nil msgp))
+
+  )
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-file-bookmarks "bookmark+")
+(defun bmkp-bmenu-mark-file-bookmarks (&optional arg msgp) ; Bound to `F M' in bookmark list
+  "Mark file bookmarks.
+With a prefix argument, do not mark remote files or directories."
+  (interactive "P\np")
+  (bmkp-bmenu-mark-bookmarks-satisfying
+   (if arg 'bmkp-local-file-bookmark-p 'bmkp-file-bookmark-p nil msgp)))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-function-bookmarks "bookmark+")
+(defun bmkp-bmenu-mark-function-bookmarks (&optional msgp) ; Bound to `Q M' in bookmark list
+  "Mark function bookmarks."
+  (interactive "p")
+  (bmkp-bmenu-mark-bookmarks-satisfying #'bmkp-function-bookmark-p nil msgp))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-gnus-bookmarks "bookmark+")
+(defun bmkp-bmenu-mark-gnus-bookmarks (&optional msgp) ; Bound to `G M' in bookmark list
+  "Mark Gnus bookmarks."
+  (interactive "p")
+  (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-gnus-bookmark-p nil msgp))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-icicles-search-hits-bookmarks "bookmark+")
+(defun bmkp-bmenu-mark-icicles-search-hits-bookmarks (&optional msgp) ; Bound to `i M' in bookmark list
+  "Mark Icicles search-hit bookmarks."
+  (interactive "p")
+  (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-icicles-search-hits-bookmark-p nil msgp))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-image-bookmarks "bookmark+")
+(defun bmkp-bmenu-mark-image-bookmarks (&optional msgp) ; Bound to `M-I M-M' in bookmark list
+  "Mark image-file bookmarks."
+  (interactive "p")
+  (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-image-bookmark-p nil msgp))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-info-bookmarks "bookmark+")
+(defun bmkp-bmenu-mark-info-bookmarks (&optional msgp) ; Bound to `I M' in bookmark list
+  "Mark Info bookmarks."
+  (interactive "p")
+  (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-info-bookmark-p nil msgp))
+
+(when (featurep 'bookmark+-lit)
+  (defun bmkp-bmenu-mark-lighted-bookmarks (&optional msgp) ; Bound to `H M' in bookmark list
+    "Mark the highlighted bookmarks."
+    (interactive "p")
+    (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-lighted-p nil msgp)))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-man-bookmarks "bookmark+")
+(defun bmkp-bmenu-mark-man-bookmarks (&optional msgp) ; Bound to `M M' in bookmark list
+  "Mark `man' page bookmarks."
+  (interactive "p")
+  (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-man-bookmark-p nil msgp))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-non-file-bookmarks "bookmark+")
+(defun bmkp-bmenu-mark-non-file-bookmarks (&optional msgp) ; Bound to `B M' in bookmark list
+  "Mark non-file bookmarks."
+  (interactive "p")
+  (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-non-file-bookmark-p nil msgp))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-non-invokable-bookmarks "bookmark+")
+(defun bmkp-bmenu-mark-non-invokable-bookmarks (&optional msgp) ; Bound to `N M' in bookmark list
+  "Mark non-invokable bookmarks."
+  (interactive "p")
+  (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-non-invokable-bookmark-p nil msgp))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-orphaned-local-file-bookmarks "bookmark+")
+(defun bmkp-bmenu-mark-orphaned-local-file-bookmarks (&optional arg msgp) ; Bound to `O M' in bookmark list
+  "Mark orphaned local-file bookmarks (their recorded files are not readable).
+With a prefix argument, mark also remote orphaned files or directories."
+  (interactive "P\np")
+  (bmkp-bmenu-mark-bookmarks-satisfying
+   (if arg 'bmkp-orphaned-file-bookmark-p 'bmkp-orphaned-local-file-bookmark-p nil msgp)))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-region-bookmarks "bookmark+")
+(defun bmkp-bmenu-mark-region-bookmarks (&optional msgp) ; Bound to `R M' in bookmark list
+  "Mark bookmarks that record a region."
+  (interactive "p")
+  (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-region-bookmark-p nil msgp))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-snippet-bookmarks "bookmark+")
+(defun bmkp-bmenu-mark-snippet-bookmarks (&optional msgp) ; Bound to `w M' in bookmark list
+  "Mark snippet bookmarks."
+  (interactive "p")
+  (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-snippet-bookmark-p nil msgp))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-specific-buffer-bookmarks "bookmark+")
+(defun bmkp-bmenu-mark-specific-buffer-bookmarks (&optional buffer msgp) ; `= b M' in bookmark list
+  "Mark bookmarks for BUFFER.
+Interactively, read the name of the buffer.
+If BUFFER is non-nil, set `bmkp-last-specific-buffer' to it."
+  (interactive (list (bmkp-completing-read-buffer-name) t))
+  (when buffer (setq bmkp-last-specific-buffer  buffer))
+  (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-last-specific-buffer-p nil msgp))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-specific-file-bookmarks "bookmark+")
+(defun bmkp-bmenu-mark-specific-file-bookmarks (&optional file msgp) ; Bound to `= f M' in bookmark list
+  "Mark bookmarks for FILE, an absolute file name.
+Interactively, read the file name.
+If FILE is non-nil, set `bmkp-last-specific-file' to it."
+  (interactive (list (bmkp-completing-read-file-name) t))
+  (when file (setq bmkp-last-specific-file  file))
+  (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-last-specific-file-p nil msgp))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-temporary-bookmarks "bookmark+")
+(defun bmkp-bmenu-mark-temporary-bookmarks (&optional msgp) ; Bound to `X M' in bookmark list
+  "Mark temporary bookmarks."
+  (interactive "p")
+  (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-temporary-bookmark-p nil msgp))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-variable-list-bookmarks "bookmark+")
+(defun bmkp-bmenu-mark-variable-list-bookmarks (&optional msgp) ; Bound to `V M' in bookmark list
+  "Mark variable-list bookmarks."
+  (interactive "p")
+  (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-variable-list-bookmark-p nil msgp))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-url-bookmarks "bookmark+")
+(defun bmkp-bmenu-mark-url-bookmarks (&optional msgp) ; Bound to `M-u M-m' in bookmark list
+  "Mark URL bookmarks."
+  (interactive "p")
+  (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-url-bookmark-p nil msgp))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-w3m-bookmarks "bookmark+")
+(defun bmkp-bmenu-mark-w3m-bookmarks (&optional msgp) ; Bound to `W 3 M' in bookmark list
+  "Mark W3M (URL) bookmarks."
+  (interactive "p")
+  (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-w3m-bookmark-p nil msgp))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-bookmarks-satisfying "bookmark+")
+(defun bmkp-bmenu-mark-bookmarks-satisfying (pred &optional no-re-sort-p msg-p) ; Not bound
+  "Mark bookmarks that satisfy predicate PRED.
+If you use this interactively, you are responsible for entering a
+symbol that names a unnary predicate.  The function you provide is not
+checked - it is simply applied to each bookmark to test it.
+
+If any bookmark was unmarked before, and if the sort order is marked
+first or last (`s >'), then re-sort.
+
+Non-interactively:
+* Non-nil optional arg NO-RE-SORT-P inhibits re-sorting.
+* Non-nil optional arg MSG-P means display a status message."
+  (interactive "aPredicate: \ni\np")
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (let ((count      0)
+        (nb-marked  (length bmkp-bmenu-marked-bookmarks))
+        bmk)
+    (save-excursion
+      (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines)
+      (when msg-p (message "Updating bookmark-list display..."))
+      (while (not (eobp))
+        (setq bmk  (bookmark-bmenu-bookmark))
+        (if (not (funcall pred bmk))
+            (forward-line 1)
+          (bookmark-bmenu-mark 'NO-RE-SORT-P)
+          (setq count  (1+ count)))))
+    (unless no-re-sort-p
+      ;; If some were unmarked before, and if sort order is `s >', then re-sort.
+      (when (and (equal bmkp-sort-comparer '((bmkp-marked-cp) bmkp-alpha-p))
+                 (< nb-marked (length bmkp-bmenu-marked-bookmarks)))
+        (let ((curr-bmk  (bookmark-bmenu-bookmark)))
+          (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P)
+          (when curr-bmk (bmkp-bmenu-goto-bookmark-named curr-bmk)))))
+    (when msg-p (if (= 1 count) (message "1 bookmark matched") (message "%d bookmarks matched" count)))))
+
+;;;###autoload (autoload 'bmkp-bmenu-toggle-marks "bookmark+")
+(defun bmkp-bmenu-toggle-marks (&optional backup no-re-sort-p msg-p) ; Bound to `t' in bookmark list
+  "Toggle marks: Unmark all marked bookmarks; mark all unmarked bookmarks.
+This affects only the `>' mark, not the `D' flag.
+
+Interactively or with nil optional arg NO-RE-SORT-P, if the current
+sort order is marked first or last (`s >'), then re-sort.
+
+Non-interactively, non-nil optional arg MSG-P means display a status
+message."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bookmark-bmenu-ensure-position)
+  (let ((marked-count    0)
+        (unmarked-count  0))
+    (save-excursion
+      (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines)
+      (if (not (bmkp-some-marked-p bmkp-latest-bookmark-alist))
+          (bmkp-bmenu-mark-all no-re-sort-p)
+        (when msg-p (message "Updating bookmark-list display..."))
+        (while (not (eobp))
+          (cond ((bmkp-bookmark-name-member (bookmark-bmenu-bookmark) bmkp-bmenu-marked-bookmarks)
+                 (bookmark-bmenu-unmark nil 'NO-RE-SORT-P)
+                 (setq unmarked-count  (1+ unmarked-count)))
+                (t
+                 (bookmark-bmenu-mark 'NO-RE-SORT-P)
+                 (setq marked-count  (1+ marked-count)))))))
+    ;; If sort order is `s >' then re-sort.
+    (when (and (not no-re-sort-p)  (equal bmkp-sort-comparer '((bmkp-marked-cp) bmkp-alpha-p)))
+      (let ((curr-bmk  (bookmark-bmenu-bookmark)))
+        (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P)
+        (when curr-bmk (bmkp-bmenu-goto-bookmark-named curr-bmk))))
+    (when msg-p (message "Marked: %d, unmarked: %d" marked-count unmarked-count))))
+
+;;;###autoload (autoload 'bmkp-bmenu-toggle-marked-temporary/savable "bookmark+")
+(defun bmkp-bmenu-toggle-marked-temporary/savable () ; Bound to `M-X' in bookmark list
+  "Toggle the temporary/savable status of each marked bookmark.
+If none are marked, toggle status of the bookmark of the current line."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (let ((o-str       (and (not (bmkp-looking-at-p "^>"))  (bookmark-bmenu-bookmark)))
+        (o-point     (point))
+        (count-temp  0)
+        (count-save  0)
+        bmk)
+    (message "Toggling temporary status of marked bookmarks...")
+    (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines)
+    (while (re-search-forward "^>" (point-max) t)
+      (bmkp-toggle-temporary-bookmark (setq bmk  (bookmark-bmenu-bookmark)))
+      (if (bmkp-temporary-bookmark-p bmk)
+          (setq count-temp  (1+ count-temp))
+        (setq count-save  (1+ count-save))))
+    (cond ((and (<= count-temp 0)  (<= count-save 0))
+           (if o-str
+               (bmkp-bmenu-goto-bookmark-named o-str)
+             (goto-char o-point)
+             (beginning-of-line))
+           (bmkp-toggle-temporary-bookmark (bookmark-bmenu-bookmark) 'MSG)
+           (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P))
+          (t
+           (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P)
+           (message "%d made temporary; %d made savable" count-temp count-save)))
+    (if o-str
+        (bmkp-bmenu-goto-bookmark-named o-str)
+      (goto-char o-point)
+      (beginning-of-line)))
+  (when (and (fboundp 'fit-frame-if-one-window)
+             (eq (selected-window) (get-buffer-window (get-buffer-create bmkp-bmenu-buffer) 0)))
+    (fit-frame-if-one-window)))
+
+;;;###autoload (autoload 'bmkp-bmenu-toggle-temporary "bookmark+")
+(defun bmkp-bmenu-toggle-temporary ()   ; Bound to `C-M-X' in bookmark list
+  "Toggle whether bookmark of current line is temporary (not saved to disk)."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (let ((o-str    (bookmark-bmenu-bookmark))
+        (o-point  (point)))
+    (bmkp-toggle-temporary-bookmark (bookmark-bmenu-bookmark) 'MSG)
+    (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P)
+    (if o-str
+        (bmkp-bmenu-goto-bookmark-named o-str)
+      (goto-char o-point)
+      (beginning-of-line))))
+
+;;;###autoload (autoload 'bmkp-bmenu-dired-marked "bookmark+")
+(defun bmkp-bmenu-dired-marked (dirbufname &optional include-omitted-p)
+                                        ; Bound to `M-d >' in bookmark list
+  "Dired in another window for the marked file and directory bookmarks.
+Absolute file names are used for the entries in the Dired buffer.
+The only entries are for the marked files and directories.  These can
+be located anywhere.  (In Emacs versions prior to release 23.2, remote
+bookmarks are ignored, because of Emacs bug #5478.)
+
+You are prompted for the Dired buffer name.  The `default-directory'
+of the buffer is the same as that of buffer `*Bookmark List*'.
+
+Omitted bookmarks are excluded, by default.  With a prefix arg, any
+that are marked are included."
+  (interactive (list (read-string "Dired buffer name: ") current-prefix-arg))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (let ((files  ())
+        file)
+    (dolist (bmk  (bmkp-sort-omit (bmkp-bmenu-marked-or-this-or-all nil include-omitted-p)))
+      (when (or (bmkp-local-file-bookmark-p bmk)
+                (> emacs-major-version 23)
+                (and (= emacs-major-version 23)  (> emacs-minor-version 1)))
+        (setq file  (bookmark-get-filename bmk))
+        (unless (file-name-absolute-p file) (setq file (expand-file-name file))) ; Should not happen.
+        (push file files)))
+    (dired-other-window (cons dirbufname files))))
+
+;;;###autoload (autoload 'bmkp-bmenu-delete-marked "bookmark+")
+(defun bmkp-bmenu-delete-marked (&optional no-confirm-p)      ; Bound to `D' in bookmark list
+  "Delete all (visible) bookmarks that are marked `>', after confirmation.
+Optional arg NO-CONFIRM-P non-nil means do not ask for confirmation."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bookmark-bmenu-execute-deletions 'MARKED 'NO-CONFIRM))
+
+;;;###autoload (autoload 'bmkp-bmenu-move-marked-to-bookmark-file "bookmark+")
+(defun bmkp-bmenu-move-marked-to-bookmark-file (file &optional duplicates-ok include-omitted-p batchp)
+                                        ; Bound to `Y > -' in bookmark list
+  "Move the marked bookmarks to bookmark file FILE.
+You are prompted for FILE.
+The marked bookmarks are removed from the current bookmark list and
+appended to those in FILE.  If any of them has the same name as a
+bookmark already in FILE then it is renamed by appending a numeric
+suffix \"<N>\" (N=2,3...).
+
+Normally, any of the marked bookmarks that are already present in FILE
+are ignored, rather than duplicating them under a new, suffixed name.
+But if you use a non-negative prefix arg then such duplication is
+allowed.
+
+If no bookmark is marked then move the bookmark of the current line.
+
+Omitted bookmarks are excluded, by default.  With a non-positive
+prefix arg, any that are marked are included.
+
+The bookmarks are removed from the currently displayed bookmark list,
+but the bookmark file associated with it is not saved automatically.
+To save it, use \\<bookmark-bmenu-mode-map>`\\[bookmark-bmenu-save]' (as usual).
+
+Non-interactively, non-nil optional arg BATCHP means do not prompt to
+confirm moving to new, empty file if no existing file."
+  (interactive
+   (list (let* ((_IGNORE      (bmkp-bmenu-barf-if-not-in-menu-list))
+                (std-default  (bmkp-default-bookmark-file))
+                (default      (if (bmkp-same-file-p bmkp-current-bookmark-file bmkp-last-bookmark-file)
+                                  (if (bmkp-same-file-p bmkp-current-bookmark-file std-default)
+                                      (and (not (bmkp-same-file-p bmkp-current-bookmark-file
+                                                                  bookmark-default-file))
+                                           bookmark-default-file)
+                                    std-default)
+                                bmkp-last-bookmark-file)))
+           (bmkp-read-bookmark-file-name "Move marked bookmarks to bookmark file: "
+                                         (or (and default  (file-name-directory default))  "~/")
+                                         default))
+         (and current-prefix-arg  (>= (prefix-numeric-value current-prefix-arg) 0))
+         (and current-prefix-arg  (<= (prefix-numeric-value current-prefix-arg) 0))))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (when (and (not (file-readable-p file))
+             (not batchp)
+             (not (y-or-n-p (format "Move to NEW, EMPTY bookmark file `%s'? " file))))
+    (error "OK - canceled"))
+  (bmkp-bmenu-copy-marked-to-bookmark-file file duplicates-ok include-omitted-p 'MOVE 'BATCH))
+
+;;;###autoload (autoload 'bmkp-bmenu-copy-marked-to-bookmark-file "bookmark+")
+(defun bmkp-bmenu-copy-marked-to-bookmark-file (file &optional duplicates-ok include-omitted-p movep batchp)
+                                        ; Bound to `Y > +' in bookmark list
+  "Copy the marked bookmarks to bookmark file FILE.
+You are prompted for FILE.
+The marked bookmarks are appended to those already in FILE.
+If any of them has the same name as a bookmark already in FILE then it
+is renamed by appending a numeric suffix \"<N>\" (N=2,3...).
+
+Normally, any of the marked bookmarks that are already present in FILE
+are ignored, rather than duplicating them under a new, suffixed name.
+But if you use a non-negative prefix arg then such duplication is
+allowed.  Use this, for example, to duplicate a bookmark in the
+current bookmark file (use that file as FILE).
+
+If no bookmark is marked then copy the bookmark of the current line.
+
+Omitted bookmarks are excluded, by default.  With a non-positive
+prefix arg, any that are marked are included.
+
+Non-interactively:
+* Non-nil MOVEP means delete the bookmarks copied.
+* Non-nil BATCHP means do not prompt to confirm moving to a new, empty
+  file if there is no existing file."
+  (interactive
+   (list (let* ((_IGNORE      (bmkp-bmenu-barf-if-not-in-menu-list))
+                (std-default  (bmkp-default-bookmark-file))
+                (default      (if (bmkp-same-file-p bmkp-current-bookmark-file bmkp-last-bookmark-file)
+                                  (if (bmkp-same-file-p bmkp-current-bookmark-file std-default)
+                                      (and (not (bmkp-same-file-p bmkp-current-bookmark-file
+                                                                  bookmark-default-file))
+                                           bookmark-default-file)
+                                    std-default)
+                                bmkp-last-bookmark-file)))
+           (bmkp-read-bookmark-file-name "Copy marked bookmarks to bookmark file: "
+                                         (or (and default  (file-name-directory default))  "~/")
+                                         default))
+         (and current-prefix-arg  (>= (prefix-numeric-value current-prefix-arg) 0))
+         (and current-prefix-arg  (<= (prefix-numeric-value current-prefix-arg) 0))))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (when (file-directory-p file) (error "`%s' is a directory, not a file" file))
+  (when (and (not (file-readable-p file))
+             (not batchp)
+             (not (y-or-n-p (format "Copy to NEW, EMPTY bookmark file `%s'? " file))))
+    (error "OK - canceled"))
+  (let ((bookmark-save-flag  nil)       ; Inhibit auto-saving for the duration.
+        imported)
+    (let ((marked-bmks                        (bmkp-sort-omit
+                                               (bmkp-bmenu-marked-or-this-or-all nil include-omitted-p)))
+          (bookmark-alist                     bookmark-alist)
+          (bookmark-alist-modification-count  bookmark-alist-modification-count))
+      (when (and (not (zerop bookmark-alist-modification-count)) ; Unsaved changes.
+                 (yes-or-no-p "Unsaved changes.  Save bookmarks before copying? "))
+        (bookmark-save))
+      (with-current-buffer (let ((enable-local-variables  ())) (find-file-noselect file))
+        (goto-char (point-min))
+        (if (file-exists-p file)
+            (bookmark-maybe-upgrade-file-format)
+          (delete-region (point-min) (point-max)) ; In case a find-file hook inserted a header etc.
+          (if (boundp 'bookmark-file-coding-system) ; Insert timestamp and an empty bookmark list.
+              (bookmark-insert-file-format-version-stamp bookmark-file-coding-system) ; Emacs 25.2+
+            (bookmark-insert-file-format-version-stamp))
+          (insert "(\n)"))
+        (let ((blist  (bookmark-alist-from-buffer)))
+          (unless (listp blist) (error "Invalid bookmark list in file `%s'" file))
+          (setq bookmark-alist  blist)  ; Bookmarks in FILE
+          (setq imported  (bookmark-import-new-list marked-bmks duplicates-ok 'RETURN-BMKS))
+          (if (and (zerop (nth 0 imported))  (zerop (nth 1 imported)))
+              (unless batchp (message "No changes"))
+            (unless batchp (message "%d added, %d renamed" (nth 1 imported) (nth 0 imported)))
+            (bookmark-write-file file)))))
+    ;; (Exit `let', to restore `bookmark-alist'.)
+    (cond (movep
+           ;; Moved.  Delete moved bookmarks.  Refresh from memory w/o asking.
+           (dolist (bmk  (nth 2 imported)) (bookmark-delete bmk 'BATCHP))
+           (bmkp-bmenu-refresh-menu-list nil 'MSGP))
+          ((not (zerop (nth 0 imported)))
+           ;; Copied, and some were renamed.  Refresh from file w/o asking.
+           (bookmark-load bmkp-current-bookmark-file 'OVERWRITE 'BATCH-NO-SAVE)
+           (bmkp-refresh-menu-list (bookmark-bmenu-bookmark))))))
+
+;;;###autoload (autoload 'bmkp-bmenu-create-bookmark-file-from-marked "bookmark+")
+(defun bmkp-bmenu-create-bookmark-file-from-marked (file create-b-f-bookmark-p
+                                                    &optional include-omitted-p batchp)
+                                        ; Bound to `Y > 0' in bookmark list
+  "Create bookmark file FILE by copying the marked bookmarks.
+You are prompted for FILE.
+They are not deleted from the current bookmark file.  To delete them, use \
+\\<bookmark-bmenu-mode-map>`\\[bmkp-bmenu-delete-marked]'.
+
+With a non-negative prefix arg, create also a bookmark-file bookmark
+for FILE.  You are prompted for the bookmark name.
+
+If no bookmark is marked then copy the bookmark of the current line.
+
+Omitted bookmarks are excluded, by default.  With a non-positive
+prefix arg, any that are marked are included.
+
+Non-interactively, non-nil optional arg BATCHP means do not prompt to
+confirm moving to new, empty file if no existing file."
+  (interactive
+   (list (let* ((_IGNORE      (bmkp-bmenu-barf-if-not-in-menu-list))
+                (std-default  (bmkp-default-bookmark-file))
+                (default      (if (bmkp-same-file-p bmkp-current-bookmark-file bmkp-last-bookmark-file)
+                                  (if (bmkp-same-file-p bmkp-current-bookmark-file std-default)
+                                      (and (not (bmkp-same-file-p bmkp-current-bookmark-file
+                                                                  bookmark-default-file))
+                                           bookmark-default-file)
+                                    std-default)
+                                bmkp-last-bookmark-file)))
+           (bmkp-read-bookmark-file-name "Create bookmark file from marked: "
+                                         (or (and default  (file-name-directory default))  "~/")
+                                         default))
+         (and current-prefix-arg  (>= (prefix-numeric-value current-prefix-arg) 0))
+         (and current-prefix-arg  (<= (prefix-numeric-value current-prefix-arg) 0))))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (when (and (file-readable-p file)
+             (not (file-directory-p file))
+             (not batchp)
+             (not (y-or-n-p (format "File `%s' already exists.  Overwrite? " file))))
+    (error "OK - canceled"))
+  (bmkp-empty-file file)
+  (bmkp-bmenu-copy-marked-to-bookmark-file file nil include-omitted-p nil 'BATCH)
+  (when create-b-f-bookmark-p (bmkp-set-bookmark-file-bookmark file)))
+
+;;;###autoload (autoload 'bmkp-bmenu-set-bookmark-file-bookmark-from-marked "bookmark+")
+(defun bmkp-bmenu-set-bookmark-file-bookmark-from-marked (file &optional include-omitted-p batchp)
+                                        ; Same as `C-u Y > 0' in bookmark list (but not bound).
+  "Set a bookmark-file bookmark for the marked bookmarks.
+You are prompted for the names of the new bookmark file and the
+bookmark-file bookmark.
+
+This is the same as using a non-negative prefix arg with
+`bmkp-bmenu-create-bookmark-file-from-marked'.
+
+If no bookmark is marked then use the bookmark of the current line.
+
+Omitted bookmarks are excluded, by default.  With a prefix arg, any
+that are marked are included.
+
+Non-interactively, non-nil optional arg BATCHP means do not prompt to
+confirm moving to new, empty file if no existing file."
+  (interactive
+   (list (let* ((_IGNORE      (bmkp-bmenu-barf-if-not-in-menu-list))
+                (std-default  (bmkp-default-bookmark-file))
+                (default      (if (bmkp-same-file-p bmkp-current-bookmark-file bmkp-last-bookmark-file)
+                                  (if (bmkp-same-file-p bmkp-current-bookmark-file std-default)
+                                      (and (not (bmkp-same-file-p bmkp-current-bookmark-file
+                                                                  bookmark-default-file))
+                                           bookmark-default-file)
+                                    std-default)
+                                bmkp-last-bookmark-file)))
+           (bmkp-read-bookmark-file-name "Create a bookmark file from marked: "
+                                         (or (and default  (file-name-directory default))  "~/")
+                                         default))
+         current-prefix-arg))
+  (bmkp-bmenu-create-bookmark-file-from-marked file 'CREATE-B-F-BMK include-omitted-p batchp))
+
+;;;###autoload (autoload 'bmkp-bmenu-load-marked-bookmark-file-bookmarks "bookmark+")
+(defun bmkp-bmenu-load-marked-bookmark-file-bookmarks (&optional msg-p) ; Bound to `M-l' in bookmark list
+  "Load the bookmark-file bookmarks that are marked, in display order.
+Non bookmark-file bookmarks that are marked are ignored.
+You can sort the bookmark-list display to change the load order.
+
+NOTE: Automatically saving the current bookmark list is turned OFF
+before loading, and it remains turned off until you explicitly turn it
+back on.  Bookmark+ does not assume that you want to automatically
+save all of the newly loaded bookmarks in the same bookmark file.  If
+you do, just use \\<bookmark-bmenu-mode-map>`\\[bmkp-toggle-saving-bookmark-file]' \
+to turn saving back on."
+  (interactive "p")
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (let ((bmks  (bmkp-remove-if-not #'bmkp-bookmark-file-bookmark-p
+                                   (bmkp-remove-if-not 'bmkp-marked-bookmark-p bmkp-sorted-alist)))
+        (bmk   (bookmark-bmenu-bookmark)))
+    (unless bmks (error "No marked bookmark-file bookmarks"))
+    ;; Maybe save bookmarks first.
+    (when (or (not msg-p)
+              (and (> bookmark-alist-modification-count 0)
+                   (condition-case err
+                       (yes-or-no-p "Save current bookmarks? (`C-g': cancel load too) ")
+                     (quit  (error "OK - canceled"))
+                     (error (error (error-message-string err))))))
+      (bookmark-save))
+    (when (or (not msg-p)
+              (yes-or-no-p "Load the marked bookmark-file bookmarks? ")
+              (error "OK - canceled"))
+      (when bookmark-save-flag          ; Turn off autosaving.
+        (bmkp-toggle-saving-bookmark-file) ; No MSG-P arg - issue message below.
+        (when bookmark-save-flag  (setq bookmark-save-flag  nil)) ; Be sure it's off.
+        (when msg-p (message "Autosaving of current bookmark file is now OFF")))
+      (when msg-p (message "Loading marked bookmark files..."))
+      (dolist (bmk  bmks)               ; Load.
+        ;; USE BATCHP: Do not refresh list or display messages here - do that after iterate.
+        (bookmark-load (bookmark-get-filename bmk) nil 'BATCHP))
+      ;; $$$$$$ Should we do (bmkp-tags-list) here to update the tags cache?
+      (bmkp-refresh-menu-list bmk (not msg-p)) ; Refresh after iterate.
+      (when msg-p (message "Autosaving is now OFF.  Loaded: %s"
+                           (mapconcat (lambda (bmk) (format "`%s'" (bmkp-bookmark-name-from-record bmk)))
+                                      bmks
+                                      ", "))))))
+
+;;;###autoload (autoload 'bmkp-bmenu-load-marking "bookmark+")
+(defun bmkp-bmenu-load-marking (file &optional unmark-first-p)
+  "Like `bookmark-load', but mark the bookmarks that are loaded.
+With a prefix arg, unmark all bookmarks first."
+  (interactive
+   (list (let ((default  (if (bmkp-same-file-p bmkp-current-bookmark-file bmkp-last-bookmark-file)
+                             (bmkp-default-bookmark-file)
+                           bmkp-last-bookmark-file)))
+           (bmkp-read-bookmark-file-name "Add bookmarks from file: "
+                                         (or (file-name-directory default)  "~/")
+                                         default
+                                         t))
+         current-prefix-arg))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (when unmark-first-p (bmkp-bmenu-unmark-all ?\r))
+  (let* ((bmkp-read-bookmark-file-hook  bmkp-read-bookmark-file-hook)
+         (bmks-read                     (bookmark-load file)))
+    (bmkp-bmenu-mark-bookmarks-satisfying
+     `(lambda (bmk) (bmkp-get-bookmark-in-alist bmk t ',bmks-read)))
+    bmks-read))                         ; Return list of bookmarks read.
+
+;;;###autoload (autoload 'bmkp-bmenu-load-marking-unmark-first "bookmark+")
+(defun bmkp-bmenu-load-marking-unmark-first (file)
+  "Like `bmkp-bmenu-load-marking' with a prefix arg: unmark all first."
+  (interactive
+   (list (let ((default  (if (bmkp-same-file-p bmkp-current-bookmark-file bmkp-last-bookmark-file)
+                             (bmkp-default-bookmark-file)
+                           bmkp-last-bookmark-file)))
+           (bmkp-read-bookmark-file-name "Add bookmarks from file: "
+                                         (or (file-name-directory default)  "~/")
+                                         default
+                                         t))))
+  (bmkp-bmenu-load-marking file t))
+
+;;;###autoload (autoload 'bmkp-bmenu-make-sequence-from-marked "bookmark+")
+(defun bmkp-bmenu-make-sequence-from-marked (seqname &optional dont-omit-p) ; Not bound
+  "Create or update a sequence bookmark from the visible marked bookmarks.
+The bookmarks that are currently marked are recorded as a sequence, in
+their current order in buffer `*Bookmark List*'.
+When you \"jump\" to the sequence bookmark, the bookmarks in the
+sequence are processed in order.
+
+By default, omit the marked bookmarks, after creating the sequence.
+With a prefix arg, do not omit them.
+
+If a bookmark with the specified name already exists, it is
+overwritten.  If a sequence bookmark with the name already exists,
+then you are prompted whether to add the marked bookmarks to the
+beginning of the existing sequence (or simply replace it).
+
+Note that another existing sequence bookmark can be marked, and thus
+included in the sequence bookmark created or updated.  That is, you
+can include other sequences within a sequence bookmark.
+
+Returns the bookmark (internal record) created or updated."
+  (interactive "sName of sequence bookmark: \nP")
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (let ((marked-bmks  ())
+        (count        0))
+    (message "Making sequence from marked bookmarks...")
+    (save-excursion (with-current-buffer bmkp-bmenu-buffer
+                      (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines)
+                      (while (re-search-forward "^>" (point-max) t)
+                        (push (bookmark-bmenu-bookmark) marked-bmks)
+                        (setq count  (1+ count)))))
+    (when (zerop count) (error "No marked bookmarks"))
+    (bmkp-set-sequence-bookmark seqname (nreverse marked-bmks)))
+  (let ((new  (bmkp-get-bookmark seqname 'NOERROR)))
+    (unless (memq new bmkp-latest-bookmark-alist)
+      (setq bmkp-latest-bookmark-alist  (cons new bmkp-latest-bookmark-alist)))
+    (unless dont-omit-p
+      (bmkp-bmenu-omit-marked)
+      (message (substitute-command-keys "Marked bookmarks now OMITTED - use \
+\\<bookmark-bmenu-mode-map>`\\[bmkp-bmenu-show-only-omitted-bookmarks]' to show")))
+    (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P)
+    (bmkp-bmenu-goto-bookmark-named seqname)
+    new))
+
+
+;;(@* "Omitted Bookmarks")
+;;  *** Omitted Bookmarks ***
+
+;;;###autoload (autoload 'bmkp-bmenu-omit "bookmark+")
+(defun bmkp-bmenu-omit ()               ; Not bound
+  "Omit this bookmark."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bookmark-bmenu-ensure-position)
+  (push (bookmark-bmenu-bookmark) bmkp-bmenu-omitted-bookmarks)
+  (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P)
+  (message "Omitted 1 bookmark"))
+
+;;;###autoload (autoload 'bmkp-bmenu-omit/unomit-marked "bookmark+")
+(defun bmkp-bmenu-omit/unomit-marked () ; Bound to `- >' in bookmark list
+  "Omit all marked bookmarks or, if showing only omitted ones, unomit."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (if (eq bmkp-bmenu-filter-function  'bmkp-omitted-alist-only)
+      (bmkp-bmenu-unomit-marked)
+    (bmkp-bmenu-omit-marked)))
+
+;;;###autoload (autoload 'bmkp-bmenu-omit-marked "bookmark+")
+(defun bmkp-bmenu-omit-marked ()        ; Bound to `- >' in bookmark list
+  "Omit all marked bookmarks.
+They will henceforth be invisible to the bookmark list.
+You can, however, use \\<bookmark-bmenu-mode-map>`\\[bmkp-bmenu-show-only-omitted-bookmarks]' \
+to see them.
+You can then mark some of them and use `\\[bmkp-bmenu-omit/unomit-marked]' to make those marked
+ available again for the bookmark list."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (let ((o-str    (and (not (bmkp-looking-at-p "^>"))  (bookmark-bmenu-bookmark)))
+        (o-point  (point))
+        (count    0))
+    (message "Omitting marked bookmarks...")
+    (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines)
+    (while (re-search-forward "^>" (point-max) t)
+      (setq bmkp-bmenu-omitted-bookmarks  (cons (bookmark-bmenu-bookmark) bmkp-bmenu-omitted-bookmarks)
+            count                         (1+ count)))
+    (if (<= count 0)
+        (message "No marked bookmarks")
+      (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P)
+      (message "Omitted %d bookmarks" count))
+    (if o-str
+        (bmkp-bmenu-goto-bookmark-named o-str)
+      (goto-char o-point)
+      (beginning-of-line)))
+  (when (and (fboundp 'fit-frame-if-one-window)
+             (eq (selected-window) (get-buffer-window (get-buffer-create bmkp-bmenu-buffer) 0)))
+    (fit-frame-if-one-window)))
+
+;;;###autoload (autoload 'bmkp-bmenu-unomit-marked "bookmark+")
+(defun bmkp-bmenu-unomit-marked ()      ; `- >' in bookmark list when showing omitted bookmarks
+  "Remove all marked bookmarks from the list of omitted bookmarks.
+They will henceforth be available for display in the bookmark list.
+\(In order to see and then mark omitted bookmarks you must use \\<bookmark-bmenu-mode-map>\
+`\\[bmkp-bmenu-show-only-omitted-bookmarks]'.)"
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (unless bmkp-bmenu-omitted-bookmarks (error "No omitted bookmarks to UN-omit"))
+  (unless (eq bmkp-bmenu-filter-function  'bmkp-omitted-alist-only)
+    (error "You must use command `bmkp-bmenu-show-only-omitted-bookmarks' first"))
+  (let ((count    0))
+    (message "UN-omitting marked bookmarks...")
+    (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines)
+    (while (re-search-forward "^>" (point-max) t)
+      (let ((bmk-name  (bookmark-bmenu-bookmark)))
+        (when (bmkp-bookmark-name-member bmk-name bmkp-bmenu-omitted-bookmarks)
+          (setq bmkp-bmenu-omitted-bookmarks  (bmkp-delete-bookmark-name-from-list
+                                               bmk-name bmkp-bmenu-omitted-bookmarks)
+                count                         (1+ count)))))
+    (if (<= count 0)
+        (message "No marked bookmarks")
+      (setq bmkp-bmenu-filter-function  nil
+            bmkp-bmenu-title            "All Bookmarks"
+            bmkp-latest-bookmark-alist  bookmark-alist)
+      (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P)
+      (message "UN-omitted %d bookmarks" count)))
+  (when (and (fboundp 'fit-frame-if-one-window)
+             (eq (selected-window) (get-buffer-window (get-buffer-create bmkp-bmenu-buffer) 0)))
+    (fit-frame-if-one-window)))
+
+;;;###autoload (autoload 'bmkp-bmenu-show-only-omitted-bookmarks "bookmark+")
+(defun bmkp-bmenu-show-only-omitted-bookmarks ()  ; Bound to `- S' in bookmark list to show only omitted
+  "Show only the omitted bookmarks.
+You can then mark some of them and use `\\<bookmark-bmenu-mode-map>\\[bmkp-bmenu-omit/unomit-marked]' to
+ make those that are marked available again for the bookmark list."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (unless bmkp-bmenu-omitted-bookmarks (error "No omitted bookmarks")) ; Cannot use macro for this.
+  (setq bmkp-bmenu-filter-function  'bmkp-omitted-alist-only
+        bmkp-bmenu-title            "Omitted Bookmarks")
+  (let ((bookmark-alist  (funcall bmkp-bmenu-filter-function)))
+    (setq bmkp-latest-bookmark-alist  bookmark-alist)
+    (bookmark-bmenu-list 'filteredp))
+  (when (interactive-p)
+    (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only omitted bookmarks are shown now")))
+
+
+;;(@* "Search-and-Replace Locations of Marked Bookmarks")
+;;  *** Search-and-Replace Locations of Marked Bookmarks ***
+
+(when (> emacs-major-version 22)
+  (defun bmkp-bmenu-isearch-marked-bookmarks (&optional allp include-omitted-p)
+                                        ; Bound to `M-s a C-s' in bookmark list
+    "Isearch the marked bookmark locations, in their current order.
+If no bookmark is marked, search the bookmark of the current line.
+
+With a non-negative prefix arg, search all bookmarks.
+
+Omitted bookmarks are excluded, by default.  With a negative prefix
+arg, any that are marked are included."
+    (interactive (list (and current-prefix-arg  (>= (prefix-numeric-value current-prefix-arg) 0))
+                       (and current-prefix-arg  (<  (prefix-numeric-value current-prefix-arg) 0))))
+    (bmkp-bmenu-barf-if-not-in-menu-list)
+    (let ((bookmarks        (mapcar #'car (bmkp-sort-omit
+                                           (bmkp-bmenu-marked-or-this-or-all allp include-omitted-p))))
+          (bmkp-use-region  nil))       ; Suppress region handling.
+      (bmkp-isearch-bookmarks bookmarks))) ; Defined in `bookmark+-1.el'.
+
+  (defun bmkp-bmenu-isearch-marked-bookmarks-regexp (&optional allp include-omitted-p)
+                                        ; `M-s a M-C-s' in bookmark list
+    "Regexp Isearch the marked bookmark locations, in their current order.
+If no bookmark is marked, search the bookmark of the current line.
+
+With a non-negative prefix arg, search all bookmarks.
+
+Omitted bookmarks are excluded, by default.  With a negative prefix
+arg, any that are marked are included."
+    (interactive (list (and current-prefix-arg  (>= (prefix-numeric-value current-prefix-arg) 0))
+                       (and current-prefix-arg  (<  (prefix-numeric-value current-prefix-arg) 0))))
+    (bmkp-bmenu-barf-if-not-in-menu-list)
+    (let ((bookmarks        (mapcar #'car (bmkp-sort-omit
+                                           (bmkp-bmenu-marked-or-this-or-all allp include-omitted-p))))
+          (bmkp-use-region  nil))       ; Suppress region handling.
+      (bmkp-isearch-bookmarks-regexp bookmarks)))) ; Defined in `bookmark+-1.el'.
+
+;;;###autoload (autoload 'bmkp-bmenu-search-marked-bookmarks-regexp "bookmark+")
+(defun bmkp-bmenu-search-marked-bookmarks-regexp (regexp &optional allp include-omitted-p)
+                                        ; `M-s a M-s' in bookmark list
+  "Search the marked file bookmarks, in their current order, for REGEXP.
+Use `\\[tags-loop-continue]' to advance among the search hits.
+Marked directory and non-file bookmarks are ignored.
+
+If no bookmark is marked, search the bookmark of the current line.
+
+With a non-negative prefix arg, search all bookmarks.
+
+Omitted bookmarks are excluded, by default.  With a negative prefix
+arg, any that are marked are included."
+  (interactive (list (bmkp-read-regexp "Search marked file bookmarks (regexp): ")
+                     (and current-prefix-arg  (>= (prefix-numeric-value current-prefix-arg) 0))
+                     (and current-prefix-arg  (<  (prefix-numeric-value current-prefix-arg) 0))))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (tags-search regexp '(let ((files  ())
+                             file)
+                        (dolist (bmk  (bmkp-sort-omit
+                                       (bmkp-bmenu-marked-or-this-or-all allp include-omitted-p)))
+                          (setq file  (bookmark-get-filename bmk))
+                          (when (and (not (equal bmkp-non-file-filename file))
+                                     (not (file-directory-p file)))
+                            (push file files)))
+                        (setq files  (nreverse files)))))
+
+;;;###autoload (autoload 'bmkp-bmenu-query-replace-marked-bookmarks-regexp "bookmark+")
+(defun bmkp-bmenu-query-replace-marked-bookmarks-regexp (from to ; Bound to `M-q' in bookmark list
+                                                         &optional delimited include-omitted-p)
+  "`query-replace-regexp' FROM with TO, for all marked file bookmarks.
+If you exit (`\\[keyboard-quit]', `RET' or `q'), you can use `\\[tags-loop-continue]' to resume where
+you left off.
+
+If no bookmark is marked, act on the bookmark of the current line.
+
+A non-negative prefix arg means replace only word-delimited matches.
+
+Omitted bookmarks are excluded, by default.  With a non-positive
+prefix arg, any that are marked are included."
+  (interactive (let ((common  (query-replace-read-args "Query replace regexp in marked files" t t)))
+                 (list (nth 0 common)
+                       (nth 1 common)
+                       (and current-prefix-arg  (>= (prefix-numeric-value current-prefix-arg) 0))
+                       (and current-prefix-arg  (<= (prefix-numeric-value current-prefix-arg) 0)))))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (tags-query-replace from to delimited
+                     '(let ((files  ())
+                             file)
+                        (dolist (bmk  (bmkp-sort-omit
+                                       (bmkp-bmenu-marked-or-this-or-all nil include-omitted-p)))
+                          (setq file  (bookmark-get-filename bmk))
+                          (let ((buffer  (get-file-buffer file)))
+                            (when (and buffer  (with-current-buffer buffer buffer-read-only))
+                              (error "File `%s' is visited read-only" file)))
+                          (when (and (not (equal bmkp-non-file-filename file))
+                                     (not (file-directory-p file)))
+                            (push file files)))
+                        (setq files  (nreverse files)))))
+
+
+;;(@* "Tags")
+;;  *** Tags ***
+
+;; Not bound, but `T 0' is `bmkp-remove-all-tags'.
+;;;###autoload (autoload 'bmkp-bmenu-remove-all-tags "bookmark+")
+(defun bmkp-bmenu-remove-all-tags (&optional must-confirm-p)
+  "Remove all tags from this bookmark.
+Interactively, you are required to confirm."
+  (interactive "p")
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bookmark-bmenu-ensure-position)
+  (let ((bookmark  (bookmark-bmenu-bookmark)))
+    (when (and must-confirm-p  (null (bmkp-get-tags bookmark)))
+      (error "Bookmark has no tags to remove"))
+    (when (or (not must-confirm-p)  (y-or-n-p "Remove all tags from this bookmark? "))
+      (bmkp-remove-all-tags bookmark))))
+
+;;;###autoload (autoload 'bmkp-bmenu-add-tags "bookmark+")
+(defun bmkp-bmenu-add-tags ()           ; Only on `mouse-3' menu in bookmark list.
+  "Add some tags to this bookmark."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bookmark-bmenu-ensure-position)
+  (let ((nb-added  (bmkp-add-tags (bookmark-bmenu-bookmark) (bmkp-read-tags-completing))))
+    (when (and (< nb-added 0)           ; It was untagged but is now tagged.  If `s t' then re-sort.
+               (equal bmkp-sort-comparer '((bmkp-tagged-cp) bmkp-alpha-p))) ; Hardcoded value, for now.
+      (bmkp-bmenu-sort-tagged-before-untagged))
+    nb-added))
+
+;;;###autoload (autoload 'bmkp-bmenu-set-tag-value "bookmark+")
+(defun bmkp-bmenu-set-tag-value ()      ; Bound to `T v' in bookmark list
+  "Set the value of one of this bookmark's tags."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bookmark-bmenu-ensure-position)
+  (let ((this-bmk  (bookmark-bmenu-bookmark)))
+    (bmkp-set-tag-value
+     this-bmk
+     (bmkp-read-tag-completing "Tag: " (mapcar 'bmkp-full-tag (bmkp-get-tags this-bmk)))
+     (read (read-string "Value: "))
+     nil
+     'MSG)))
+
+;;;###autoload (autoload 'bmkp-bmenu-set-tag-value-for-marked "bookmark+")
+(defun bmkp-bmenu-set-tag-value-for-marked (tag value &optional allp include-omitted-p msg-p)
+                                        ; Bound to `T > v' in bookmark list
+  "Set the value of TAG to VALUE, for each of the marked bookmarks.
+If any of the bookmarks has no tag named TAG, then add one with VALUE.
+
+If no bookmark is marked, act on the bookmark of the current line.
+
+With a non-negative prefix arg, act on all bookmarks.
+
+Omitted bookmarks are excluded, by default.  With a negative prefix
+arg, any that are marked are included.
+
+Non-interactively, non-nil MSG-P means display messages."
+  (interactive (list (bmkp-read-tag-completing)
+                     (read (read-string "Value: "))
+                     (and current-prefix-arg  (>= (prefix-numeric-value current-prefix-arg) 0))
+                     (and current-prefix-arg  (<  (prefix-numeric-value current-prefix-arg) 0))
+                     'MSG))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (when msg-p (message "Setting tag values..."))
+  (let ((marked  (bmkp-bmenu-marked-or-this-or-all allp include-omitted-p)))
+    (unless marked (error "No marked bookmarks"))
+    (when msg-p (message "Setting tag values..."))
+    (bmkp-set-tag-value-for-bookmarks marked tag value))
+  (when (and msg-p  tag) (message "Setting tag values...done")))
+
+;;;###autoload (autoload 'bmkp-bmenu-remove-tags "bookmark+")
+(defun bmkp-bmenu-remove-tags (&optional msg-p) ; Only on `mouse-3' menu in bookmark list.
+  "Remove some tags from this bookmark.
+Non-interactively, non-nil MSG-P means display messages."
+  (interactive "p")
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bookmark-bmenu-ensure-position)
+  (let* ((bmk         (bookmark-bmenu-bookmark))
+         (nb-removed  (bmkp-remove-tags bmk
+                                        (bmkp-read-tags-completing
+                                         (mapcar 'bmkp-full-tag (bmkp-get-tags bmk)) t)
+                                        nil
+                                        msg-p)))
+    (when (and (< nb-removed 0)         ; It was tagged but is now untagged.  If `s t' then re-sort.
+               (equal bmkp-sort-comparer '((bmkp-tagged-cp) bmkp-alpha-p))) ; Hardcoded value, for now.
+      (bmkp-bmenu-sort-tagged-before-untagged))
+    nb-removed))
+
+;;;###autoload (autoload 'bmkp-bmenu-add-tags-to-marked "bookmark+")
+(defun bmkp-bmenu-add-tags-to-marked (tags &optional allp include-omitted-p msg-p)
+                                        ; Bound to `T > +' in bookmark list
+  "Add TAGS to each of the marked bookmarks.
+Hit `RET' to enter each tag, then hit `RET' again after the last tag.
+You can use completion to enter each tag, but you are not limited to
+choosing existing tags.
+
+If no bookmark is marked, act on the bookmark of the current line.
+
+With a non-negative prefix arg, act on all bookmarks.
+
+Omitted bookmarks are excluded, by default.  With a negative prefix
+arg, any that are marked are included.
+
+Non-interactively:
+ TAGS is a list of strings.
+ Non-nil MSG-P means display messages."
+  (interactive (list (bmkp-read-tags-completing)
+                     (and current-prefix-arg  (>= (prefix-numeric-value current-prefix-arg) 0))
+                     (and current-prefix-arg  (<  (prefix-numeric-value current-prefix-arg) 0))
+                     'MSG))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (let ((marked                (bmkp-bmenu-marked-or-this-or-all allp include-omitted-p))
+        (curr-bmk              (bookmark-bmenu-bookmark))
+        (some-were-untagged-p  nil))
+    (unless marked (error "No marked bookmarks"))
+    (when msg-p (message "Adding tags..."))
+    (let ((bookmark-save-flag  (and (not bmkp-count-multi-mods-as-one-flag)
+                                    bookmark-save-flag))) ; Save at most once, after `dolist'.
+      (dolist (bmk  (mapcar #'car marked))
+        (when (< (bmkp-add-tags bmk tags 'NO-UPDATE-P) 0)  (setq some-were-untagged-p  t))))
+    (bmkp-tags-list)                    ; Update the tags cache now, after iterate.
+    (bmkp-maybe-save-bookmarks)         ; Increments `bookmark-alist-modification-count'.
+    (bmkp-refresh-menu-list curr-bmk (not msg-p)) ; Refresh after iterate.
+    (when (and some-were-untagged-p  (equal bmkp-sort-comparer '((bmkp-tagged-cp) bmkp-alpha-p)))
+      (bmkp-bmenu-sort-tagged-before-untagged))
+    (when (and msg-p  tags) (message "Tags added: %S" tags))))
+
+;;;###autoload (autoload 'bmkp-bmenu-remove-tags-from-marked "bookmark+")
+(defun bmkp-bmenu-remove-tags-from-marked (tags &optional allp include-omitted-p msg-p)
+                                        ; Bound to `T > -' in bookmark list
+  "Remove TAGS from each of the marked bookmarks.
+Hit `RET' to enter each tag, then hit `RET' again after the last tag.
+You can use completion to enter each tag.
+
+If no bookmark is marked, act on the bookmark of the current line.
+
+With a non-negative prefix arg, act on all bookmarks.
+
+Omitted bookmarks are excluded, by default.  With a negative prefix
+arg, any that are marked are included.
+
+Non-interactively, non-nil MSG-P means display messages."
+  (interactive
+   (let ((tgs  ())
+         (all  (and current-prefix-arg  (>= (prefix-numeric-value current-prefix-arg) 0)))
+         (omt  (and current-prefix-arg  (<  (prefix-numeric-value current-prefix-arg) 0))))
+           
+     (dolist (bmk  (bmkp-bmenu-marked-or-this-or-all all omt))
+       (setq tgs  (bmkp-set-union tgs (bmkp-get-tags bmk))))
+     (unless tgs (error "No tags to remove"))
+     (list (bmkp-read-tags-completing tgs t) all omt 'MSG)))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (let ((marked    (if allp
+                       bookmark-alist
+                     (or (if include-omitted-p
+                             (bmkp-marked-bookmarks-only)
+                           (bmkp-remove-if #'bmkp-omitted-bookmark-p (bmkp-marked-bookmarks-only)))
+                         (and (bookmark-bmenu-bookmark)
+                              (list (bmkp-get-bookmark (bookmark-bmenu-bookmark)))))))
+        (curr-bmk  (bookmark-bmenu-bookmark))
+        (some-are-now-untagged-p  nil))
+    (unless marked (error "No marked bookmarks"))
+    (when msg-p (message "Removing tags..."))
+    (let ((bookmark-save-flag  (and (not bmkp-count-multi-mods-as-one-flag)
+                                    bookmark-save-flag))) ; Save at most once, after `dolist'.
+      (dolist (bmk  (mapcar #'car marked))
+        (when (< (bmkp-remove-tags bmk tags 'NO-UPDATE-P) 0)  (setq some-are-now-untagged-p  t))))
+    (bmkp-tags-list)                    ; Update the tags cache now, after iterate.
+    (bmkp-maybe-save-bookmarks)         ; Increments `bookmark-alist-modification-count'.
+    (bmkp-refresh-menu-list curr-bmk (not msg-p)) ; Refresh after iterate.
+    (when (and some-are-now-untagged-p  (equal bmkp-sort-comparer '((bmkp-tagged-cp) bmkp-alpha-p)))
+      (bmkp-bmenu-sort-tagged-before-untagged))
+    (when (and msg-p  tags) (message "Tags removed: %S" tags))))
+
+;;;###autoload (autoload 'bmkp-bmenu-list-tags-of-marked "bookmark+")
+(defun bmkp-bmenu-list-tags-of-marked (fullp &optional msg-p)
+                                        ; Bound to `T > l' in bookmark list
+  "List the tags used in the marked bookmarks.
+Show the list in the minibuffer or, if not enough space, in buffer
+`*All Tags*'.  The tags are listed alphabetically, respecting option
+`case-fold-search'.
+
+With no prefix arg, list only the tag names.  With a prefix arg, list
+the full alist of tags.  Note that when the full tags alist is shown,
+the same tag name appears once for each of its different values.
+
+Non-interactively, non-nil MSG-P means display a status message."
+  (interactive "P\np")
+  (require 'pp)
+  (when msg-p (message "Gathering tags..."))
+  (pp-display-expression (sort (let ((bookmark-alist  (bmkp-marked-bookmarks-only))
+                                     bmkp-tags-alist) ; Prevent updating it.
+                                 (bmkp-tags-list (not fullp) t))
+                               (if fullp
+                                   (lambda (t1 t2) (bmkp-string-less-case-fold-p (car t1) (car t2)))
+                                 'bmkp-string-less-case-fold-p))
+                         "*Tags of Marked Bookmarks*"))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-bookmarks-tagged-regexp "bookmark+")
+(defun bmkp-bmenu-mark-bookmarks-tagged-regexp (regexp &optional notp no-re-sort-p msg-p)
+                                        ; `T m %' in bookmark list
+  "Mark bookmarks any of whose tags match REGEXP.
+With a prefix arg, mark all that are tagged but have no matching tags.
+
+If any bookmark was unmarked before, and if the sort order is marked
+first or last (`s >'), then re-sort.
+
+Non-interactively:
+* Non-nil NOTP: see prefix arg, above.
+* Non-nil optional arg NO-RE-SORT-P inhibits re-sorting.
+* Non-nil optional arg MSG-P means display a status message."
+  (interactive (list (bmkp-read-regexp "Regexp: ") current-prefix-arg nil
+                     (prefix-numeric-value current-prefix-arg)))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (let ((count      0)
+        (nb-marked  (length bmkp-bmenu-marked-bookmarks))
+        tags anyp)
+    (save-excursion
+      (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines)
+      (when msg-p (message "Updating bookmark-list display..."))
+      (while (not (eobp))
+        (setq tags  (bmkp-get-tags (bookmark-bmenu-bookmark))
+              anyp  (and tags  (bmkp-some (lambda (tag) (bmkp-string-match-p regexp (bmkp-tag-name tag)))
+                                          tags)))
+        (if (not (and tags  (if notp (not anyp) anyp)))
+            (forward-line 1)
+          (bookmark-bmenu-mark 'NO-RE-SORT-P)
+          (setq count  (1+ count)))))
+    (unless no-re-sort-p
+      ;; If some were unmarked before, and if sort order is `s >', then re-sort.
+      (when (and (equal bmkp-sort-comparer '((bmkp-marked-cp) bmkp-alpha-p))
+                 (/= nb-marked (length bmkp-bmenu-marked-bookmarks)))
+        (let ((curr-bmk  (bookmark-bmenu-bookmark)))
+          (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P)
+          (when curr-bmk (bmkp-bmenu-goto-bookmark-named curr-bmk)))))
+    (when msg-p (if (= 1 count) (message "1 bookmark matched") (message "%d bookmarks matched" count)))))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-bookmarks-tagged-all "bookmark+")
+(defun bmkp-bmenu-mark-bookmarks-tagged-all (tags &optional nonep msg-p) ; `T m *' in bookmark list
+  "Mark all visible bookmarks that are tagged with *each* tag in TAGS.
+As a special case, if TAGS is empty, then mark the bookmarks that have
+any tags at all (i.e., at least one tag).
+
+With a prefix arg, mark all that are *not* tagged with *any* TAGS."
+  (interactive (list (bmkp-read-tags-completing) current-prefix-arg 'MSG))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bmkp-bmenu-mark/unmark-bookmarks-tagged-all/none tags nonep nil nil msg-p))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-bookmarks-tagged-none "bookmark+")
+(defun bmkp-bmenu-mark-bookmarks-tagged-none (tags &optional allp msg-p) ; `T m ~ +' in bookmark list
+  "Mark all visible bookmarks that are not tagged with *any* tag in TAGS.
+As a special case, if TAGS is empty, then mark the bookmarks that have
+no tags at all.
+
+With a prefix arg, mark all that are tagged with *each* tag in TAGS."
+  (interactive (list (bmkp-read-tags-completing) current-prefix-arg 'MSG))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bmkp-bmenu-mark/unmark-bookmarks-tagged-all/none tags (not allp) nil nil msg-p))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-bookmarks-tagged-some "bookmark+")
+(defun bmkp-bmenu-mark-bookmarks-tagged-some (tags &optional somenotp msg-p) ; `T m +' in bookmark list
+  "Mark all visible bookmarks that are tagged with *some* tag in TAGS.
+As a special case, if TAGS is empty, then mark the bookmarks that have
+any tags at all.
+
+With a prefix arg, mark all that are *not* tagged with *all* TAGS.
+
+Hit `RET' to enter each tag, then hit `RET' again after the last tag.
+You can use completion to enter each tag."
+  (interactive (list (bmkp-read-tags-completing) current-prefix-arg 'MSG))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bmkp-bmenu-mark/unmark-bookmarks-tagged-some/not-all tags somenotp nil nil msg-p))
+
+;;;###autoload (autoload 'bmkp-bmenu-mark-bookmarks-tagged-not-all "bookmark+")
+(defun bmkp-bmenu-mark-bookmarks-tagged-not-all (tags &optional somep msg-p) ; `T m ~ *' in bmk list
+  "Mark all visible bookmarks that are *not* tagged with *all* TAGS.
+As a special case, if TAGS is empty, then mark the bookmarks that have
+no tags at all.
+
+With a prefix arg, mark all that are tagged with *some* tag in TAGS."
+  (interactive (list (bmkp-read-tags-completing) current-prefix-arg 'MSG))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bmkp-bmenu-mark/unmark-bookmarks-tagged-some/not-all tags (not somep) nil nil msg-p))
+
+;;;###autoload (autoload 'bmkp-bmenu-unmark-bookmarks-tagged-regexp "bookmark+")
+(defun bmkp-bmenu-unmark-bookmarks-tagged-regexp (regexp &optional notp no-re-sort-p msg-p)
+                                        ; `T u %' in bookmark list
+  "Unmark bookmarks any of whose tags match REGEXP.
+With a prefix arg, mark all that are tagged but have no matching tags.
+
+If any bookmark was marked before, and if the sort order is marked
+first or last (`s >'), then re-sort.
+
+Non-interactively:
+* Non-nil NOTP: see prefix arg, above.
+* Non-nil optional arg NO-RE-SORT-P inhibits re-sorting.
+* Non-nil optional arg MSG-P means display a status message."
+  (interactive (list (bmkp-read-regexp "Regexp: ") current-prefix-arg nil
+                     (prefix-numeric-value current-prefix-arg)))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (let ((count      0)
+        (nb-marked  (length bmkp-bmenu-marked-bookmarks))
+        tags anyp)
+    (save-excursion
+      (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines)
+      (when msg-p (message "Updating bookmark-list display..."))
+      (while (not (eobp))
+        (setq tags  (bmkp-get-tags (bookmark-bmenu-bookmark))
+              anyp  (and tags  (bmkp-some (lambda (tag) (bmkp-string-match-p regexp (bmkp-tag-name tag)))
+                                          tags)))
+        (if (not (and tags  (if notp (not anyp) anyp)))
+            (forward-line 1)
+          (bookmark-bmenu-unmark nil 'NO-RE-SORT-P)
+          (setq count  (1+ count)))))
+    (unless no-re-sort-p
+      ;; If some were marked before, and if sort order is `s >', then re-sort.
+      (when (and (equal bmkp-sort-comparer '((bmkp-marked-cp) bmkp-alpha-p))
+                 (/= nb-marked (length bmkp-bmenu-marked-bookmarks)))
+        (let ((curr-bmk  (bookmark-bmenu-bookmark)))
+          (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P)
+          (when curr-bmk (bmkp-bmenu-goto-bookmark-named curr-bmk)))))
+    (when msg-p (if (= 1 count) (message "1 bookmark matched") (message "%d bookmarks matched" count)))))
+
+;;;###autoload (autoload 'bmkp-bmenu-unmark-bookmarks-tagged-all "bookmark+")
+(defun bmkp-bmenu-unmark-bookmarks-tagged-all (tags &optional nonep msg-p) ; `T u *' in bookmark list
+  "Unmark all visible bookmarks that are tagged with *each* tag in TAGS.
+As a special case, if TAGS is empty, then unmark the bookmarks that have
+any tags at all.
+
+With a prefix arg, unmark all that are *not* tagged with *any* TAGS."
+  (interactive (list (bmkp-read-tags-completing) current-prefix-arg 'MSG))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bmkp-bmenu-mark/unmark-bookmarks-tagged-all/none tags nonep 'UNMARK nil msg-p))
+
+;;;###autoload (autoload 'bmkp-bmenu-unmark-bookmarks-tagged-none "bookmark+")
+(defun bmkp-bmenu-unmark-bookmarks-tagged-none (tags &optional allp msg-p) ; `T u ~ +' in bookmark list
+  "Unmark all visible bookmarks that are *not* tagged with *any* TAGS.
+As a special case, if TAGS is empty, then unmark the bookmarks that have
+no tags at all.
+
+With a prefix arg, unmark all that are tagged with *each* tag in TAGS."
+  (interactive (list (bmkp-read-tags-completing) current-prefix-arg 'MSG))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bmkp-bmenu-mark/unmark-bookmarks-tagged-all/none tags (not allp) 'UNMARK nil msg-p))
+
+;;;###autoload (autoload 'bmkp-bmenu-unmark-bookmarks-tagged-some "bookmark+")
+(defun bmkp-bmenu-unmark-bookmarks-tagged-some (tags &optional somenotp msg-p) ; `T u +' in bmk list
+  "Unmark all visible bookmarks that are tagged with *some* tag in TAGS.
+As a special case, if TAGS is empty, then unmark the bookmarks that have
+any tags at all.
+
+With a prefix arg, unmark all that are *not* tagged with *all* TAGS."
+  (interactive (list (bmkp-read-tags-completing) current-prefix-arg 'MSG))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bmkp-bmenu-mark/unmark-bookmarks-tagged-some/not-all tags somenotp 'UNMARK nil msg-p))
+
+;;;###autoload (autoload 'bmkp-bmenu-unmark-bookmarks-tagged-not-all "bookmark+")
+(defun bmkp-bmenu-unmark-bookmarks-tagged-not-all (tags &optional somep msg-p) ; `T u ~ *' in bmk list
+  "Unmark all visible bookmarks that are *not* tagged with *all* TAGS.
+As a special case, if TAGS is empty, then unmark the bookmarks that have
+no tags at all.
+
+With a prefix arg, unmark all that are tagged with *some* TAGS."
+  (interactive (list (bmkp-read-tags-completing) current-prefix-arg 'MSG))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bmkp-bmenu-mark/unmark-bookmarks-tagged-some/not-all tags (not somep) 'UNMARK nil msg-p))
+
+(defun bmkp-bmenu-mark/unmark-bookmarks-tagged-all/none (tags &optional nonep unmarkp no-re-sort-p msg-p)
+  "Mark or unmark visible bookmarks tagged with all or none of TAGS.
+TAGS is a list of strings, the tag names.
+Non-nil NONEP means mark/unmark bookmarks that have none of the TAGS.
+Non-nil UNMARKP means unmark; nil means mark.
+Non-nil NO-RE-SORT-P inhibits re-sorting.
+Non-nil MSG-P means display a status message.
+
+As a special case, if TAGS is empty, then mark or unmark the bookmarks
+that have any tags at all, or if NONEP is non-nil then mark or unmark
+those that have no tags at all.
+
+If any bookmark was (un)marked before but is not afterward, and if the
+sort order is marked first or last (`s >'), then re-sort."
+  (with-current-buffer bmkp-bmenu-buffer
+    (let ((count      0)
+          (nb-marked  (length bmkp-bmenu-marked-bookmarks))
+          bmktags presentp)
+      (save-excursion
+        (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines)
+        (when msg-p (message "Updating bookmark-list display..."))
+        (while (not (eobp))
+          (setq bmktags  (bmkp-get-tags (bookmark-bmenu-bookmark)))
+          (if (not (if (null tags)
+                       (if nonep (not bmktags) bmktags)
+                     (and bmktags  (catch 'bmkp-b-mu-b-t-an
+                                     (dolist (tag  tags)
+                                       (setq presentp  (assoc-default tag bmktags nil t))
+                                       (unless (if nonep (not presentp) presentp)
+                                         (throw 'bmkp-b-mu-b-t-an nil)))
+                                     t))))
+              (forward-line 1)
+            (if unmarkp (bookmark-bmenu-unmark nil 'NO-RE-SORT-P) (bookmark-bmenu-mark 'NO-RE-SORT-P))
+            (setq count  (1+ count)))))
+      (unless no-re-sort-p
+        ;; If some were (un)marked before but not afterward, and if sort order is `s >', then re-sort.
+        (when (and (equal bmkp-sort-comparer '((bmkp-marked-cp) bmkp-alpha-p))
+                   (/= nb-marked (length bmkp-bmenu-marked-bookmarks)))
+          (let ((curr-bmk  (bookmark-bmenu-bookmark)))
+            (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P)
+            (when curr-bmk (bmkp-bmenu-goto-bookmark-named curr-bmk)))))
+      (when msg-p
+        (if (= 1 count) (message "1 bookmark matched") (message "%d bookmarks matched" count))))))
+
+(defun bmkp-bmenu-mark/unmark-bookmarks-tagged-some/not-all (tags &optional notallp unmarkp
+                                                             no-re-sort-p msg-p)
+  "Mark or unmark visible bookmarks tagged with any or not all of TAGS.
+TAGS is a list of strings, the tag names.
+Non-nil NOTALLP means mark/unmark bookmarks that do not have all TAGS.
+Non-nil UNMARKP means unmark; nil means mark.
+Non-nil NO-RE-SORT-P inhibits re-sorting.
+Non-nil MSG-P means display a status message.
+
+As a special case, if TAGS is empty, then mark or unmark the bookmarks
+that have any tags at all, or if NOTALLP is non-nil then mark or
+unmark those that have no tags at all.
+
+If any bookmark was (un)marked before but is not afterward, and if the
+sort order is marked first or last (`s >'), then re-sort."
+  (with-current-buffer bmkp-bmenu-buffer
+    (let ((count      0)
+          (nb-marked  (length bmkp-bmenu-marked-bookmarks))
+          bmktags presentp)
+      (save-excursion
+        (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines)
+        (when msg-p (message "Updating bookmark-list display..."))
+        (while (not (eobp))
+          (setq bmktags  (bmkp-get-tags (bookmark-bmenu-bookmark)))
+          (if (not (if (null tags)
+                       (if notallp (not bmktags) bmktags)
+                     (and bmktags  (catch 'bmkp-b-mu-b-t-sna
+                                     (dolist (tag  tags)
+                                       (setq presentp  (assoc-default tag bmktags nil t))
+                                       (when (if notallp (not presentp) presentp)
+                                         (throw 'bmkp-b-mu-b-t-sna t)))
+                                     nil))))
+              (forward-line 1)
+            (if unmarkp (bookmark-bmenu-unmark nil 'NO-RE-SORT-P) (bookmark-bmenu-mark 'NO-RE-SORT-P))
+            (setq count  (1+ count)))))
+      (unless no-re-sort-p
+        ;; If some were (un)marked before but not afterward, and if sort order is `s >', then re-sort.
+        (when (and (equal bmkp-sort-comparer '((bmkp-marked-cp) bmkp-alpha-p))
+                   (/= nb-marked (length bmkp-bmenu-marked-bookmarks)))
+          (let ((curr-bmk  (bookmark-bmenu-bookmark)))
+            (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P)
+            (when curr-bmk (bmkp-bmenu-goto-bookmark-named curr-bmk)))))
+      (when msg-p
+        (if (= 1 count) (message "1 bookmark matched") (message "%d bookmarks matched" count))))))
+
+;;;###autoload (autoload 'bmkp-bmenu-copy-tags "bookmark+")
+(defun bmkp-bmenu-copy-tags (&optional msg-p) ; `T c', `T M-w', `mouse-3' menu in bookmark list.
+  "Copy tags from this bookmark, so you can paste them to another bookmark.
+NOTE: It is by design that you can *remove all* tags from a bookmark
+by copying an empty set of tags and then pasting to that bookmark
+using replacement.  So be careful pasting with replacement.  If you
+want to be sure that you do not replace tags with an empty list of
+tags, you can check the value of variable `bmkp-copied-tags' before
+pasting."
+  (interactive (list 'MSG))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bookmark-bmenu-ensure-position)
+  (bmkp-copy-tags (bookmark-bmenu-bookmark) msg-p))
+
+;;;###autoload (autoload 'bmkp-bmenu-paste-add-tags "bookmark+")
+(defun bmkp-bmenu-paste-add-tags (&optional msg-p) ; `T p', `T C-y', `mouse-3' menu in bookmark list.
+  "Add tags to this bookmark that were copied from another bookmark."
+  (interactive (list 'MSG))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bookmark-bmenu-ensure-position)
+  (bmkp-paste-add-tags (bookmark-bmenu-bookmark) nil msg-p))
+
+;;;###autoload (autoload 'bmkp-bmenu-paste-replace-tags "bookmark+")
+(defun bmkp-bmenu-paste-replace-tags (&optional msg-p) ; `T q', `mouse-3' menu.
+  "Replace tags for this bookmark with those copied from another bookmark.
+NOTE: It is by design that you can *remove all* tags from a bookmark
+by copying an empty set of tags and then pasting to that bookmark
+using this command.  So be careful using it.  If you want to be sure
+that you do not replace tags with an empty list of tags, you can check
+the value of variable `bmkp-copied-tags' before pasting."
+  (interactive (list 'MSG))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bookmark-bmenu-ensure-position)
+  (bmkp-paste-replace-tags (bookmark-bmenu-bookmark) nil msg-p))
+
+;;;###autoload (autoload 'bmkp-bmenu-paste-add-tags-to-marked "bookmark+")
+(defun bmkp-bmenu-paste-add-tags-to-marked (&optional allp include-omitted-p msg-p)
+                                        ; Bound to `T > p', `T > C-y' in bookmark list
+  "Add tags that were copied from another bookmark to the marked bookmarks.
+If no bookmark is marked, act on the bookmark of the current line.
+
+With a non-negative prefix arg, act on all bookmarks.
+
+Omitted bookmarks are excluded, by default.  With a negative prefix
+arg, any that are marked are included.
+
+Non-interactively, non-nil MSG-P means display messages."
+  (interactive (list (and current-prefix-arg  (>= (prefix-numeric-value current-prefix-arg) 0))
+                     (and current-prefix-arg  (<  (prefix-numeric-value current-prefix-arg) 0))
+                     'MSG))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (let ((marked  (bmkp-bmenu-marked-or-this-or-all allp include-omitted-p))
+        (bmk     (bookmark-bmenu-bookmark)))
+    (unless marked (error "No marked bookmarks"))
+    (when msg-p (message "Adding tags..."))
+    (let ((bookmark-save-flag  (and (not bmkp-count-multi-mods-as-one-flag)
+                                    bookmark-save-flag))) ; Save at most once, after `dolist'.
+      (dolist (bmk  marked) (bmkp-paste-add-tags bmk 'NO-UPDATE-P)))
+    (bmkp-tags-list)                    ; Update the tags cache now, after iterate.
+    (bmkp-maybe-save-bookmarks)         ; Increments `bookmark-alist-modification-count'.
+    (bmkp-refresh-menu-list bmk (not msg-p)) ; Refresh after iterate.
+    (when msg-p (message "Tags added: %S" bmkp-copied-tags))))
+
+;;;###autoload (autoload 'bmkp-bmenu-paste-replace-tags-for-marked "bookmark+")
+(defun bmkp-bmenu-paste-replace-tags-for-marked (&optional allp include-omitted-p msg-p) ; `T > q'
+  "Replace tags for the marked bookmarks with tags copied previously.
+NOTE: It is by design that you can *remove all* tags from a bookmark
+by copying an empty set of tags and then pasting to that bookmark
+using this command.  So be careful using it.  If you want to be sure
+that you do not replace tags with an empty list of tags, you can check
+the value of variable `bmkp-copied-tags' before pasting.
+
+If no bookmark is marked, act on the bookmark of the current line.
+
+With a non-negative prefix arg, act on all bookmarks.
+
+Omitted bookmarks are excluded, by default.  With a negative prefix
+arg, any that are marked are included.
+
+Non-interactively, non-nil MSG-P means display messages."
+  (interactive (list (and current-prefix-arg  (>= (prefix-numeric-value current-prefix-arg) 0))
+                     (and current-prefix-arg  (<  (prefix-numeric-value current-prefix-arg) 0))
+                     'MSG))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (let ((marked  (bmkp-bmenu-marked-or-this-or-all allp include-omitted-p))
+        (bmk     (bookmark-bmenu-bookmark)))
+    (unless marked (error "No marked bookmarks"))
+    (when msg-p (message "Replacing tags..."))
+    (let ((bookmark-save-flag  (and (not bmkp-count-multi-mods-as-one-flag)
+                                    bookmark-save-flag))) ; Save at most once, after `dolist'.
+      (dolist (bmk  marked) (bmkp-paste-replace-tags bmk 'NO-UPDATE-P)))
+    (bmkp-tags-list)                    ; Update the tags cache now, after iterate.
+    (bmkp-maybe-save-bookmarks)         ; Increments `bookmark-alist-modification-count'.
+    (bmkp-refresh-menu-list bmk (not msg-p)) ; Refresh after iterate.
+    (when msg-p (message "Replacement tags: %S" bmkp-copied-tags))))
+
+
+;;(@* "General Menu-List (`-*bmenu-*') Commands and Functions")
+;;  *** General Menu-List (`-*bmenu-*') Commands and Functions ***
+
+;;;###autoload (autoload 'bmkp-bmenu-create/edit-annotations-for-marked "bookmark+")
+(defun bmkp-bmenu-edit-annotations-for-marked (&optional allp include-omitted-p) ; `a >' in bookmark list
+  "Edit the annotations of the marked bookmarks, in separate buffers.
+Create an annotation for any marked bookmark that has none.
+When you finish editing, use `\\[bmkp-edit-annotations-send]'.
+The current bookmark list is then updated to reflect your edits.
+
+If no bookmark is marked, edit the annotation of the bookmark of the
+current line.
+
+With a non-negative prefix arg, edit annotations for all bookmarks.
+
+Omitted bookmarks are excluded, by default.  With a negative prefix
+arg, any that are marked are included."
+  (interactive (list (and current-prefix-arg  (>= (prefix-numeric-value current-prefix-arg) 0))
+                     (and current-prefix-arg  (<  (prefix-numeric-value current-prefix-arg) 0))))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (setq bmkp-last-bmenu-bookmark  (bookmark-bmenu-bookmark))
+  ;; No marked bookmarks.  Mark this bookmark, so that `C-c C-c' in edit buffer will find it.
+  (unless bmkp-bmenu-marked-bookmarks (bookmark-bmenu-mark))
+  ;; FIXME - Should we re-sort, if it was not annotated and now is, or vice versa, and if `s a'?
+  ;; We do that for adding/removing tags - see `bmkp-bmenu-add-tags' and `bmkp-bmenu-remove-tags'.
+  ;; If we do it, then do it also for `bookmark-bmenu-edit-annotation' (which is just vanilla, so far).
+  (let ((bmks  (bmkp-bmenu-marked-or-this-or-all allp include-omitted-p)))
+    (unless bmks (error "No marked bookmarks"))
+    (dolist (bmk  (bmkp-sort-omit bmks)) (bookmark-edit-annotation bmk))))
+
+;;;###autoload (autoload 'bmkp-bmenu-show-or-edit-annotation "bookmark+")
+(defun bmkp-bmenu-show-or-edit-annotation (editp msg-p) ; Not bound anymore.
+  "Show annotation for current bookmark in another window.  `C-u': Edit.
+With no prefix arg, show the annotation.  With a prefix arg, edit it."
+  (interactive "P\np")
+  (if editp (bookmark-bmenu-edit-annotation) (bookmark-bmenu-show-annotation msg-p)))
+
+;;;###autoload (autoload 'bmkp-bmenu-jump-to-marked "bookmark+")
+(defun bmkp-bmenu-jump-to-marked ()
+  "Jump to each bookmark marked `>', in another window.
+Unlike `bookmark-bmenu-select', this command:
+* does not bury buffer `*Bookmark List*' or replace it in its window
+* does not unmark the marked bookmarks
+* does not include the current bookmark - only the marked are accessed"
+  (interactive)
+  (dolist (bmk  bmkp-bmenu-marked-bookmarks)
+    (bookmark-jump-other-window bmk)))
+
+;;;###autoload (autoload 'bmkp-bmenu-w32-open "bookmark+")
+(defun bmkp-bmenu-w32-open ()           ; Bound to `M-RET' in bookmark list.
+  "Use `w32-browser' to open this bookmark."
+  (interactive) (let ((bmkp-use-w32-browser-p  t))  (bookmark-bmenu-this-window)))
+
+;; $$$$$$ FIXME?: If `Open' action opens a window-manager window, it might be behind all Emacs frames.
+;;;###autoload (autoload 'bmkp-bmenu-w32-open-with-mouse "bookmark+")
+(defun bmkp-bmenu-w32-open-with-mouse (event) ; Bound to `M-mouse-2' in bookmark list.
+  "Use `w32-browser' to open the bookmark clicked."
+  (interactive "e")
+  (let ((bmkp-use-w32-browser-p  t)
+        (bmk                     (with-current-buffer (window-buffer (posn-window (event-end event)))
+                                   (bmkp-bmenu-barf-if-not-in-menu-list)
+                                   (save-excursion (goto-char (posn-point (event-end event)))
+                                                   (bookmark-bmenu-bookmark)))))
+    (unless bmk (error "No bookmark here"))
+    (bookmark-handle-bookmark bmk)
+    ;; Probably do not want this.  Users can use `jump-fn' tag if need be.
+    ;; (let ((orig-buff  (current-buffer))) ; Used by `crosshairs-highlight'.
+    ;;   (run-hooks 'bookmark-after-jump-hook))
+    (let ((jump-fn  (bmkp-get-tag-value bmk "bmkp-jump")))
+      (when jump-fn (funcall jump-fn)))
+    (when bookmark-automatically-show-annotations (bookmark-show-annotation bmk))))
+
+;;;###autoload (autoload 'bmkp-bmenu-w32-jump-to-marked "bookmark+")
+(defun bmkp-bmenu-w32-jump-to-marked ()    ; Bound to `M-o' in bookmark-list.
+  "Use `w32-browser' to open this bookmark and all marked bookmarks."
+  (interactive) (let ((bmkp-use-w32-browser-p  t))  (bmkp-bmenu-jump-to-marked)))
+
+;;;###autoload (autoload 'bmkp-bmenu-mode-status-help "bookmark+")
+(defun bmkp-bmenu-mode-status-help ()   ; Bound to `C-h m' and `?' in bookmark list
+  "`describe-mode' + current status of `*Bookmark List*' + face legend."
+  (interactive)
+  (unless (string= (buffer-name) "*Help*") (bmkp-bmenu-barf-if-not-in-menu-list))
+  (with-current-buffer (get-buffer-create "*Help*")
+    (bmkp-with-help-window "*Help*"
+      (let ((buffer-read-only  nil)
+            top)
+        (erase-buffer)
+        (save-excursion
+          (let ((standard-output  (current-buffer)))
+            (if (> emacs-major-version 21)
+                (describe-function-1 'bookmark-bmenu-mode)
+              (describe-function-1 'bookmark-bmenu-mode nil t)))
+          (help-setup-xref (list #'bmkp-bmenu-mode-status-help) (interactive-p))
+          (goto-char (point-min))
+          (search-forward               ; This depends on the text written by `bookmark-bmenu-mode'.
+           "More bookmarking help below." nil t)
+          (delete-region (point-min) (point)) ; Get rid of intro from `describe-function'.
+          (insert "*************************** Bookmark List ***************************\n\n")
+          (insert "Major mode for editing a list of bookmarks.\n")
+          (insert "Each line in `*Bookmark List*' represents an Emacs bookmark.\n")
+          (setq top  (copy-marker (point)))
+          ;; Add buttons to access help and Customize.
+          ;; Not for Emacs 21.3 - its `help-insert-xref-button' signature is different.
+          (when (and (> emacs-major-version 21) ; In `help-mode.el'.
+                     (condition-case nil (require 'help-mode nil t) (error nil))
+                     (fboundp 'help-insert-xref-button))
+            (goto-char (point-min))
+            (help-insert-xref-button "[Doc in Commentary]" 'bmkp-commentary-button)
+            (insert "           ")
+            (help-insert-xref-button "[Doc on the Web]" 'bmkp-help-button)
+            (insert "           ")
+            (help-insert-xref-button "[Customize]" 'bmkp-customize-button)
+            (insert "\n\n")
+            (goto-char (point-max))
+            (insert (substitute-command-keys
+                     "\nSend a Bookmark+ bug report: `\\[bmkp-send-bug-report]'.\n\n"))
+            (help-insert-xref-button "[Doc in Commentary]" 'bmkp-commentary-button)
+            (insert "           ")
+            (help-insert-xref-button "[Doc on the Web]" 'bmkp-help-button)
+            (insert "           ")
+            (help-insert-xref-button "[Customize]" 'bmkp-customize-button)
+            (insert "\n\n")
+            (goto-char (point-min))
+            (forward-line 2))
+          (goto-char top)
+          (insert (format
+                   "\n\nCurrent Status\n--------------\n
+Bookmark file:\t%s\nSorted:\t\t\t%s\nFiltering:\t\t%s\nMarked:\t\t\t%d\nOmitted:\t\t%d\n\
+Autosave bookmarks:\t%s\nAutosave list display:\t%s\n\n\n"
+                   bmkp-current-bookmark-file
+                   (if (not bmkp-sort-comparer)
+                       "no"
+                     (format "%s%s" (or (bmkp-current-sort-order)  "")
+                             ;; Code essentially the same as found in `bmkp-msg-about-sort-order'.
+                             (if (not (and (consp bmkp-sort-comparer) ; Ordinary single predicate
+                                           (consp (car bmkp-sort-comparer))))
+                                 (if bmkp-reverse-sort-p "; reversed" "")
+                               (if (not (cadr (car bmkp-sort-comparer)))
+                                   ;; Single PRED.
+                                   (if (or (and bmkp-reverse-sort-p  (not bmkp-reverse-multi-sort-p))
+                                           (and bmkp-reverse-multi-sort-p  (not bmkp-reverse-sort-p)))
+                                       "; reversed"
+                                     "")
+                                 ;; In case we want to distinguish:
+                                 ;; (if (and bmkp-reverse-sort-p
+                                 ;;          (not bmkp-reverse-multi-sort-p))
+                                 ;;     "; reversed"
+                                 ;;   (if (and bmkp-reverse-multi-sort-p
+                                 ;;            (not bmkp-reverse-sort-p))
+                                 ;;       "; reversed +"
+                                 ;;     ""))
+
+                                 ;; At least two PREDs.
+                                 (cond ((and bmkp-reverse-sort-p  (not bmkp-reverse-multi-sort-p))
+                                        "; reversed")
+                                       ((and bmkp-reverse-multi-sort-p  (not bmkp-reverse-sort-p))
+                                        "; each predicate group reversed")
+                                       ((and bmkp-reverse-multi-sort-p  bmkp-reverse-sort-p)
+                                        "; order of predicate groups reversed")
+                                       (t ""))))))
+                   (or (and bmkp-bmenu-filter-function  (downcase bmkp-bmenu-title))  "none")
+                   (length bmkp-bmenu-marked-bookmarks)
+                   (length bmkp-bmenu-omitted-bookmarks)
+                   (if bookmark-save-flag "yes" "no")
+                   (if bmkp-bmenu-state-file "yes" "no")))
+
+          ;; Add markings legend.
+          (let ((mm   "  >")
+                (DD   "  D")
+                (tt   "  t")
+                (aa   "  a")
+                (XX   "  X")
+                (mod  "  *"))
+            (put-text-property 2 3 'face 'bmkp->-mark mm)
+            (put-text-property 2 3 'face 'bmkp-D-mark DD)
+            (put-text-property 2 3 'face 'bmkp-t-mark tt)
+            (put-text-property 2 3 'face 'bmkp-a-mark aa)
+            (put-text-property 2 3 'face 'bmkp-X-mark XX)
+            (put-text-property 2 3 'face 'bmkp-*-mark mod)
+            (insert "Legend for Markings\n-------------------\n\n")
+            (insert (concat mm  "  marked\n"))
+            (insert (concat DD  "  flagged for deletion                     (`x' to delete all such)\n"))
+            (insert (concat tt  "  tagged                                   (`C-h C-RET' to see)\n"))
+            (insert (concat aa  "  annotated                                (`C-h C-RET' to see)\n"))
+            (insert (concat mod "  modified (not saved)\n"))
+            (insert (concat XX  "  temporary (will not be saved)\n"))
+            (insert "\n\n"))
+
+          ;; Add face legend.
+          (let ((gnus             "Gnus\n")
+                (no-jump          "Bookmarks you cannot jump to from `*Bookmark List*'\n")
+                (info             "Info node\n")
+                (man              "Man page\n")
+                (url              "URL\n")
+                (local-no-region  "Local file with no region\n")
+                (local-w-region   "Local file with a region\n")
+                (no-file          "No such local file\n")
+                (buffer           "Buffer\n")
+                (no-buf           "No such buffer now\n")
+                (bad              "Possibly invalid bookmark\n")
+                (remote           "Remote file/directory or Dired buffer (could have wildcards)\n")
+                (sudo             "Remote accessed by `su' or `sudo'\n")
+                (local-dir        "Local directory or Dired buffer (could have wildcards)\n")
+                (file-handler     "Bookmark with entry `file-handler'\n")
+                (bookmark-list    "*Bookmark List*\n")
+                (bookmark-file    "Bookmark file\n")
+                (snippet          "Snippet\n")
+                (desktop          "Desktop\n")
+                (sequence         "Sequence\n")
+                (variable-list    "Variable list\n")
+                (function         "Function\n"))
+            (put-text-property 0 (1- (length gnus))          'face 'bmkp-gnus         gnus)
+            (put-text-property 0 (1- (length info))          'face 'bmkp-info         info)
+            (put-text-property 0 (1- (length man))           'face 'bmkp-man          man)
+            (put-text-property 0 (1- (length url))           'face 'bmkp-url          url)
+            (put-text-property 0 (1- (length local-no-region))
+                               'face 'bmkp-local-file-without-region                  local-no-region)
+            (put-text-property 0 (1- (length local-w-region))
+                               'face 'bmkp-local-file-with-region                     local-w-region)
+            (put-text-property 0 (1- (length no-file))       'face 'bmkp-no-local     no-file)
+            (put-text-property 0 (1- (length buffer))        'face 'bmkp-buffer       buffer)
+            (put-text-property 0 (1- (length no-buf))        'face 'bmkp-non-file     no-buf)
+            (put-text-property 0 (1- (length remote))        'face 'bmkp-remote-file  remote)
+            (put-text-property 0 (1- (length sudo))          'face 'bmkp-su-or-sudo   sudo)
+            (put-text-property 0 (1- (length local-dir))
+                               'face 'bmkp-local-directory                            local-dir)
+            (put-text-property 0 (1- (length file-handler))  'face 'bmkp-file-handler file-handler)
+            (put-text-property 0 (1- (length bookmark-list))
+                               'face 'bmkp-bookmark-list                               bookmark-list)
+            (put-text-property 0 (1- (length bookmark-file))
+                               'face 'bmkp-bookmark-file                               bookmark-file)
+            (put-text-property 0 (1- (length snippet))       'face 'bmkp-snippet       snippet)
+            (put-text-property 0 (1- (length desktop))       'face 'bmkp-desktop       desktop)
+            (put-text-property 0 (1- (length sequence))      'face 'bmkp-sequence      sequence)
+            (put-text-property 0 (1- (length variable-list)) 'face 'bmkp-variable-list variable-list)
+            (put-text-property 0 (1- (length function))      'face 'bmkp-function      function)
+            (put-text-property 0 (1- (length no-jump))       'face 'bmkp-no-jump       no-jump)
+            (put-text-property 0 (1- (length bad))           'face 'bmkp-bad-bookmark  bad)
+            (insert "Legend for Bookmark Types\n-------------------------\n\n")
+            (when (and (fboundp 'display-images-p)  (display-images-p)
+                       bmkp-bmenu-image-bookmark-icon-file
+                       (file-readable-p bmkp-bmenu-image-bookmark-icon-file))
+              (let ((image  (create-image bmkp-bmenu-image-bookmark-icon-file nil nil :ascent 95)))
+                (when image (insert "  ")  (insert-image image)  (insert " Image file\n"))))
+            (insert "  " gnus) (insert "  " info) (insert "  " man) (insert "  " url)
+            (insert "  " local-no-region) (insert "  " local-w-region) (insert "  " no-file)
+            (insert "  " buffer) (insert "  " no-buf) (insert "  " remote) (insert "  " sudo)
+            (insert "  " local-dir) (insert "  " file-handler) (insert "  " bookmark-list)
+            (insert "  " bookmark-file) (insert "  " snippet) (insert "  " desktop)
+            (insert "  " sequence) (insert "  " variable-list) (insert "  " function)
+            (insert "  " no-jump) (insert "  " bad)
+            (insert "\n\nKeys without prefix `C-x' are available only here (`*Bookmark List*').\n")
+            (insert "Keys with prefix `C-x' are available everywhere.\n\n")
+            (insert "Remember that you can see all bindings for a prefix key by hitting it,\n")
+            (insert "then `C-h'.  E.g., `s C-h' to see keys with prefix `s' (sorting).")))))))
+
+(when (and (> emacs-major-version 21)
+           (condition-case nil (require 'help-mode nil t) (error nil))
+           (get 'help-xref 'button-category-symbol)) ; In `button.el'
+  (define-button-type 'bmkp-help-button
+      :supertype 'help-xref
+      'help-function #'(lambda () (browse-url "https://www.emacswiki.org/emacs/BookmarkPlus"))
+      'help-echo
+      (purecopy "mouse-2, RET: Bookmark+ documentation on the Emacs Wiki (requires Internet access)"))
+  (define-button-type 'bmkp-commentary-button
+      :supertype 'help-xref
+      'help-function #'(lambda ()
+                         (message "Getting Bookmark+ doc from file commentary...")
+                         (finder-commentary "bookmark+-doc")
+                         (when (condition-case nil (require 'linkd nil t) (error nil)) (linkd-mode 1))
+                         (when (condition-case nil (require 'fit-frame nil t) (error nil))
+                           (fit-frame)))
+      'help-echo (purecopy "mouse-2, RET: Bookmark+ documentation (no Internet needed)"))
+  (define-button-type 'bmkp-customize-button
+      :supertype 'help-xref
+      'help-function #'(lambda () (customize-group-other-window 'bookmark-plus))
+      'help-echo (purecopy "mouse-2, RET: Customize/Browse Bookmark+ Options & Faces")))
+
+;;;###autoload (autoload 'bmkp-bmenu-define-jump-marked-command "bookmark+")
+(defun bmkp-bmenu-define-jump-marked-command () ; Bound to `C-c C-j' in bookmark list
+  "Define a command to jump to a bookmark that is one of those now marked.
+The bookmarks marked now will be those that are completion candidates
+for the command (but omitted bookmarks are excluded).
+Save the command definition in `bmkp-bmenu-commands-file'."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (let* ((cands  (mapcar #'list
+                         (bmkp-maybe-unpropertize-bookmark-names
+                          (bmkp-remove-if #'(lambda (bmk)
+                                              (bmkp-bookmark-name-member bmk bmkp-bmenu-omitted-bookmarks))
+                                          bmkp-bmenu-marked-bookmarks))))
+         (fn     (intern (read-string "Define command to jump to a bookmark now marked: " nil
+                                      bmkp-bmenu-define-command-history)))
+         (def    `(defun ,fn (bookmark-name &optional flip-use-region-p)
+                   (interactive (list (bmkp-read-bookmark-for-type nil ',cands t) current-prefix-arg))
+                   (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window flip-use-region-p))))
+    (eval def)
+    (with-current-buffer (find-file-noselect bmkp-bmenu-commands-file)
+      (goto-char (point-max))
+      (let ((print-length           nil)
+            (print-level            nil)
+            (print-circle           bmkp-propertize-bookmark-names-flag)
+            (print-gensym           bmkp-propertize-bookmark-names-flag)
+            (version-control        (case bookmark-version-control
+                                      ((nil)      nil)
+                                      (never      'never)
+                                      (nospecial  version-control)
+                                      (t          t)))
+            (require-final-newline  t)
+            (errorp                 nil))
+        (pp def (current-buffer))
+        (insert "\n")
+        (condition-case nil
+            (write-file bmkp-bmenu-commands-file)
+          (file-error (setq errorp  t) (error "CANNOT WRITE FILE `%s'" bmkp-bmenu-commands-file)))
+        (kill-buffer (current-buffer))
+        (unless errorp (message "Command `%s' defined and saved in file `%s'"
+                                fn bmkp-bmenu-commands-file))))))
+
+;;;###autoload (autoload 'bmkp-bmenu-define-command "bookmark+")
+(defun bmkp-bmenu-define-command () ; Bound to `C-c C-c' in bookmark list
+  "Define a command to use the current sort order, filter, and omit list.
+Prompt for the command name.  Save the command definition in
+`bmkp-bmenu-commands-file'.
+
+The current sort order, filter function, omit list, and title for
+buffer `*Bookmark List*' are encapsulated as part of the command.
+Use the command at any time to restore them."
+  (interactive)
+  (let* ((fn       (intern (read-string "Define sort+filter command: " nil
+                                        bmkp-bmenu-define-command-history)))
+         (_IGNORE  (when (fboundp fn)
+                     (if (y-or-n-p (format "`%s' already defined.  Redfine? " fn))
+                         (fmakunbound fn)
+                       (error "OK, canceled"))))  
+         (def      `(defun ,fn ()
+                      (interactive)
+                      (setq
+                       bmkp-sort-comparer               ',bmkp-sort-comparer
+                       bmkp-reverse-sort-p              ',bmkp-reverse-sort-p
+                       bmkp-reverse-multi-sort-p        ',bmkp-reverse-multi-sort-p
+                       bmkp-bmenu-filter-function       ',bmkp-bmenu-filter-function
+                       bmkp-bmenu-filter-pattern        ',bmkp-bmenu-filter-pattern
+                       ;; Use `copy-sequence' here, because some code modifies the list structure.
+                       bmkp-bmenu-omitted-bookmarks     (copy-sequence
+                                                         ',(bmkp-maybe-unpropertize-bookmark-names
+                                                            bmkp-bmenu-omitted-bookmarks))
+                       bmkp-bmenu-title                 ',bmkp-bmenu-title
+                       bookmark-bmenu-toggle-filenames  ',bookmark-bmenu-toggle-filenames)
+                      (bmkp-bmenu-refresh-menu-list)
+                      (when (interactive-p)
+                        (bmkp-msg-about-sort-order
+                         (car (rassoc bmkp-sort-comparer bmkp-sort-orders-alist)))))))
+    (eval def)
+    (with-current-buffer (find-file-noselect bmkp-bmenu-commands-file)
+      (goto-char (point-min)) ; Delete any preexisting defs of the same command.
+      (let (sexp)
+        (condition-case nil
+            (while (setq sexp  (read (current-buffer)))
+              (when (and (consp sexp)  (eq 'defun (car sexp))
+                         (eq fn (cadr sexp)))
+                (delete-region (point) (save-excursion (backward-sexp) (point)))))
+          (error nil)))
+      (goto-char (point-max))
+      (let ((print-length           nil)
+            (print-level            nil)
+            (print-circle           bmkp-propertize-bookmark-names-flag)
+            (print-gensym           bmkp-propertize-bookmark-names-flag)
+            (version-control        (case bookmark-version-control
+                                      ((nil)      nil)
+                                      (never      'never)
+                                      (nospecial  version-control)
+                                      (t          t)))
+            (require-final-newline  t)
+            (errorp                 nil))
+        (pp def (current-buffer))
+        (insert "\n")
+        (condition-case nil
+            (write-file bmkp-bmenu-commands-file)
+          (file-error (setq errorp  t) (error "CANNOT WRITE FILE `%s'" bmkp-bmenu-commands-file)))
+        (kill-buffer (current-buffer))
+        (unless errorp (message "Command `%s' defined and saved in file `%s'"
+                                fn bmkp-bmenu-commands-file))))))
+
+;;;###autoload (autoload 'bmkp-bmenu-define-full-snapshot-command "bookmark+")
+(defun bmkp-bmenu-define-full-snapshot-command () ; Bound to `C-c C-S-c' (aka `C-c C-C') in bookmark list
+  "Define a command to restore the current bookmark-list state.
+Prompt for the command name.  Save the command definition in
+`bmkp-bmenu-commands-file'.
+
+Be aware that the command definition can be quite large, since it
+copies the current bookmark list and accessory lists (hidden
+bookmarks, marked bookmarks, etc.).  For a lighter weight command, use
+`bmkp-bmenu-define-full-snapshot-command' instead.  That records only
+the omit list and the sort & filter information."
+  (interactive)
+  (let* ((fn       (intern (read-string "Define restore-snapshot command: " nil
+                                        bmkp-bmenu-define-command-history)))
+         (_IGNORE  (when (fboundp fn)
+                     (if (y-or-n-p (format "`%s' already defined.  Redfine? " fn))
+                         (fmakunbound fn)
+                       (error "OK, canceled"))))
+         (def      `(defun ,fn ()
+                      (interactive)
+                      ;; Use `copy-sequence' here, to avoid circular references when
+                      ;; `bmkp-propertize-bookmark-names-flag' is nil, and for other
+                      ;; strings and lists (such as `bmkp-bmenu-marked-bookmarks'),
+                      ;; because some code modifies them.
+                      ;;
+                      (setq
+                       bmkp-sort-comparer                     ',bmkp-sort-comparer
+                       bmkp-reverse-sort-p                    ',bmkp-reverse-sort-p
+                       bmkp-reverse-multi-sort-p              ',bmkp-reverse-multi-sort-p
+                       bmkp-latest-bookmark-alist             (copy-sequence
+                                                               ',(bmkp-maybe-unpropertize-bookmark-names
+                                                                  bmkp-latest-bookmark-alist))
+                       bmkp-bmenu-omitted-bookmarks           (copy-sequence
+                                                               ',(bmkp-maybe-unpropertize-bookmark-names
+                                                                  bmkp-bmenu-omitted-bookmarks 'COPY))
+                       bmkp-bmenu-marked-bookmarks            (copy-sequence
+                                                               ',(bmkp-maybe-unpropertize-bookmark-names
+                                                                  bmkp-bmenu-marked-bookmarks 'COPY))
+                       bmkp-bmenu-filter-function             ',bmkp-bmenu-filter-function
+                       bmkp-bmenu-filter-pattern              ',bmkp-bmenu-filter-pattern
+                       bmkp-bmenu-title                       ',bmkp-bmenu-title
+                       bmkp-last-bmenu-bookmark               ',(and (get-buffer bmkp-bmenu-buffer)
+                                                                     (with-current-buffer
+                                                                         (get-buffer bmkp-bmenu-buffer)
+                                                                       (bmkp-maybe-unpropertize-string
+                                                                        (bookmark-bmenu-bookmark) 'COPY)))
+                       bmkp-last-specific-buffer              ',(copy-sequence bmkp-last-specific-buffer)
+                       bmkp-last-specific-file                ',(copy-sequence bmkp-last-specific-file)
+                       bookmark-bmenu-toggle-filenames        ',bookmark-bmenu-toggle-filenames
+                       bmkp-bmenu-before-hide-marked-alist    (copy-sequence
+                                                               ',(bmkp-maybe-unpropertize-bookmark-names
+                                                                  bmkp-bmenu-before-hide-marked-alist 'COPY))
+                       bmkp-bmenu-before-hide-unmarked-alist  (copy-sequence
+                                                               ',(bmkp-maybe-unpropertize-bookmark-names
+                                                                  bmkp-bmenu-before-hide-unmarked-alist 'COPY))
+                       bmkp-last-bookmark-file                ',(copy-sequence
+                                                                 (convert-standard-filename
+                                                                  (expand-file-name bmkp-last-bookmark-file)))
+                       bmkp-current-bookmark-file             ',(copy-sequence
+                                                                 (convert-standard-filename
+                                                                  (expand-file-name
+                                                                   bmkp-current-bookmark-file))))
+                      ;; $$$$$$ (let ((bookmark-alist  (bmkp-refresh-latest-bookmark-list))) ; Sets *-latest-* also.
+                      (let ((bookmark-alist  (or bmkp-latest-bookmark-alist
+                                                 (bmkp-refresh-latest-bookmark-list)))) ; Sets *-latest-* also.
+                        (bmkp-bmenu-list-1 'filteredp nil (interactive-p)))
+                      (when bmkp-last-bmenu-bookmark
+                        (with-current-buffer (get-buffer bmkp-bmenu-buffer)
+                          (bmkp-bmenu-goto-bookmark-named bmkp-last-bmenu-bookmark)))
+                      (when (interactive-p)
+                        (bmkp-msg-about-sort-order (car (rassoc bmkp-sort-comparer bmkp-sort-orders-alist)))))))
+    (eval def)
+    (with-current-buffer (find-file-noselect bmkp-bmenu-commands-file)
+      (goto-char (point-min)) ; Delete any preexisting defs of the same command.
+      (let (sexp)
+        (condition-case nil
+            (while (setq sexp  (read (current-buffer)))
+              (when (and (consp sexp)  (eq 'defun (car sexp))
+                         (eq fn (cadr sexp)))
+                (delete-region (point) (save-excursion (backward-sexp) (point)))))
+          (error nil)))
+      (goto-char (point-max))
+      (let ((print-length           nil)
+            (print-level            nil)
+            (print-circle           bmkp-propertize-bookmark-names-flag)
+            (print-gensym           bmkp-propertize-bookmark-names-flag)
+            (version-control        (case bookmark-version-control
+                                      ((nil)      nil)
+                                      (never      'never)
+                                      (nospecial  version-control)
+                                      (t          t)))
+            (require-final-newline  t)
+            (errorp                 nil))
+        (pp def (current-buffer))
+        (insert "\n")
+        (condition-case nil
+            (write-file bmkp-bmenu-commands-file)
+          (file-error (setq errorp  t) (error "CANNOT WRITE FILE `%s'" bmkp-bmenu-commands-file)))
+        (kill-buffer (current-buffer))
+        (unless errorp (message "Command `%s' defined and saved in file `%s'"
+                                fn bmkp-bmenu-commands-file))))))
+
+;; We use this because Emacs 20 has no `print-circle' or `print-gensym'. and otherwise
+;; property `bmkp-full-record' would make the state file unreadable.
+;;
+(defun bmkp-maybe-unpropertize-bookmark-names (list &optional copy)
+  "Strip properties from the bookmark names in a copy of LIST.
+LIST is a bookmark alist or a list of bookmark names (strings).
+Return the updated copy.
+
+Note, however, that this is a shallow copy, so the names are also
+stripped within any alist elements of the original LIST.
+
+Non-nil optional arg COPY means copy also each element of LIST.  Use
+this if, for example, you have bookmark lists that share bookmarks and
+you want to treat the shared bookmarks separately.
+
+Always strip property `face' and internal Icicles properties.  Remove
+other text properties only if using Emacs 20 or if option
+`bmkp-propertize-bookmark-names-flag' is non-nil."
+  (let ((new-list   (copy-sequence list))
+        (rem-all-p  (or (not bmkp-propertize-bookmark-names-flag)
+                        (< emacs-major-version 21)))) ; Cannot just use (not (boundp 'print-circle)).
+    (dolist (bmk  new-list)
+      (when (and (consp bmk)  (stringp (car bmk))) (setq bmk  (car bmk)))
+      (when (stringp bmk)
+        (let ((len  (length bmk)))
+          (if rem-all-p
+              (set-text-properties 0 len nil bmk)
+            (remove-text-properties     ; Remove property `face' and any Icicles internal properties.
+             0 len '(face                     nil
+                     display                  nil
+                     help-echo                nil
+                     rear-nonsticky           nil
+                     icicle-fancy-candidates  nil
+                     icicle-mode-line-help    nil
+                     icicle-special-candidate nil
+                     icicle-user-plain-dot    nil
+                     icicle-whole-candidate   nil
+                     invisible                nil)
+             bmk)
+            (when (boundp 'icicle-candidate-properties-alist) ; Multi-completion indexes + text props.
+              (dolist (entry  icicle-candidate-properties-alist)
+                (put-text-property 0 len (car (cadr entry)) nil bmk)))))))
+    (if copy (mapcar #'copy-sequence new-list) new-list)))
+
+(defun bmkp-maybe-unpropertize-string (string &optional copy)
+  "Strip properties from STRING.
+Return the unpropertized STRING.
+Non-nil optional arg COPY means return a copy of the unpropertized
+STRING.  (STRING is modified before the copy is made.)
+
+Do nothing in Emacs 21 or later or if
+`bmkp-propertize-bookmark-names-flag' is non-nil.  In these cases,
+just return STRING unmodified."
+  (unless (and (> emacs-major-version 20) ; Emacs 21+.  Cannot just use (boundp 'print-circle).
+               bmkp-propertize-bookmark-names-flag)
+    (set-text-properties 0 (length string) nil string)
+    (when copy (setq string  (copy-sequence string))))
+  string)
+
+;; This is a general command.  It is in this file because it uses macro `bmkp-define-sort-command'
+;; and it is used mainly in the bookmark list display.
+;;;###autoload (autoload 'bmkp-define-tags-sort-command "bookmark+")
+(defun bmkp-define-tags-sort-command (tags &optional msg-p) ; Bound to `T s' in bookmark list
+  "Define a command to sort bookmarks in the bookmark list by tags.
+Hit `RET' to enter each tag, then hit `RET' again after the last tag.
+
+The new command sorts first by the first tag in TAGS, then by the
+second, and so on.
+
+Besides sorting for these specific tags, any bookmark that has a tag
+sorts before one that has no tags.  Otherwise, sorting is by bookmark
+name, alphabetically.
+
+The name of the new command is `bmkp-bmenu-sort-' followed by the
+specified tags, in order, separated by hyphens (`-').  E.g., for TAGS
+\(\"alpha\" \"beta\"), the name is `bmkp-bmenu-sort-alpha-beta'.
+
+If you use this function non-interactively, be sure to load library
+`bookmark+-mac.el' first."
+  (interactive
+   (progn (or (condition-case nil       ; Load `bookmark+-mac.el' when called interactively.
+                  (load-library "bookmark+-mac") ; Use load-library to ensure latest .elc.
+                (error nil))
+              (require 'bookmark+-mac))
+          (list (bmkp-read-tags-completing) 'MSG)))
+  (let ((sort-order  (concat "tags-" (mapconcat #'identity tags "-")))
+        (doc-string  (read-string "Doc string for command: "))
+        (comparer    ())
+        def)
+    (dolist (tag  tags)
+      (push `(lambda (b1 b2)
+              (let ((tags1  (bmkp-get-tags b1))
+                    (tags2  (bmkp-get-tags b2)))
+                (cond ((and (assoc-default ,tag tags1 nil t)
+                            (assoc-default ,tag tags2 nil t))  nil)
+                      ((assoc-default ,tag tags1 nil t)        '(t))
+                      ((assoc-default ,tag tags2 nil t)        '(nil))
+                      ((and tags1  tags2)                      nil)
+                      (tags1                                   '(t))
+                      (tags2                                   '(nil))
+                      (t                                       nil))))
+            comparer))
+    (setq comparer  (nreverse comparer)
+          comparer  (list comparer 'bmkp-alpha-p))
+    (eval (setq def  (macroexpand `(bmkp-define-sort-command ,sort-order ,comparer ,doc-string))))
+    (with-current-buffer (find-file-noselect bmkp-bmenu-commands-file)
+      (goto-char (point-max))
+      (let ((print-length           nil)
+            (print-level            nil)
+            (print-circle           bmkp-propertize-bookmark-names-flag)
+            (print-gensym           bmkp-propertize-bookmark-names-flag)
+            (version-control        (case bookmark-version-control
+                                      ((nil)      nil)
+                                      (never      'never)
+                                      (nospecial  version-control)
+                                      (t          t)))
+            (require-final-newline  t)
+            (errorp                 nil))
+        (pp def (current-buffer))
+        (insert "\n")
+        (condition-case nil
+            (write-file bmkp-bmenu-commands-file)
+          (file-error (setq errorp  t) (error "CANNOT WRITE FILE `%s'" bmkp-bmenu-commands-file)))
+        (kill-buffer (current-buffer))
+        (when (and msg-p  (not errorp))
+          (message "Defined and saved command `%s'" (concat "bmkp-bmenu-sort-" sort-order)))))))
+
+;;;###autoload (autoload 'bmkp-bmenu-relocate-marked "bookmark+")
+(defun bmkp-bmenu-relocate-marked (directory &optional include-omitted-p msgp)
+                                        ; Bound to `M-R' in bookmark list
+  "Relocate target files of all (visible) bookmarks that are marked `>'.
+You are prompted for the relocation target directory.
+Return the number of bookmarks relocated to DIRECTORY.
+
+Omitted bookmarks are excluded, by default.  With a prefix arg, any
+that are marked are included.
+
+Non-interactively, non-nil MSG-P means display messages."
+  (interactive (list (funcall (if (fboundp 'read-directory-name)
+                                  #'read-directory-name
+                                #'read-file-name)
+                              "Relocate targets of marked bookmarks to directory: "
+                              default-directory default-directory)
+                     current-prefix-arg
+                     'MSGP))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (let ((count  0)
+        file)
+    (dolist (bmk  (bmkp-sort-omit (bmkp-bmenu-marked-or-this-or-all nil include-omitted-p)))
+      (when (and (setq file  (bookmark-get-filename bmk))
+                 (not (equal file bmkp-non-file-filename)))
+        (setq file   (file-name-nondirectory file)
+              count  (1+ count))
+        (bookmark-set-filename bmk (expand-file-name file directory))
+        (setq bookmark-alist-modification-count
+              (1+ bookmark-alist-modification-count))))
+    (when (bookmark-time-to-save-p) (bookmark-save))
+    (bookmark-bmenu-surreptitiously-rebuild-list)
+    (when msgp
+      (if (> count 0)
+          (message "Relocated %d bookmark%s" count (if (= 1 count) "" "s"))
+        (message "No bookmarks relocated")))
+    count))
+
+;;;###autoload (autoload 'bmkp-copy-bookmark "bookmark+")
+(defalias 'bmkp-bmenu-copy-bookmark 'bmkp-bmenu-clone-bookmark)
+;;;###autoload (autoload 'bmkp-bmenu-clone-bookmark "bookmark+")
+(defun bmkp-bmenu-clone-bookmark (&optional arg confirm-overwrite-p) ; Bound to `M-n' in bookmark list
+  "Create a duplicate copy named of the bookmark under the cursor.
+The clone name is the same as that bookmark, but with \"<2>\" appended.
+With a prefix arg you are instead prompted for the clone name."
+  (interactive "P\np")
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bookmark-bmenu-ensure-position)
+  (let* ((orig     (bookmark-bmenu-bookmark))
+         ;; Remove any `bmkp-full-record' property from name.
+         (_IGNORE  (remove-text-properties 0 (length orig) '(bmkp-full-record nil) orig))
+         (default  (concat orig "<2>"))
+         (new      (if arg
+                       (bmkp-completing-read-lax "Clone name" default)
+                     default)))
+    (while (equal orig new)
+      (setq new  (bmkp-completing-read-lax "Clone name (must be different)" default)))
+    ;; Remove any `bmkp-full-record' property from name.
+    (remove-text-properties 0 (length new) '(bmkp-full-record nil) new)
+    (bmkp-clone-bookmark orig new confirm-overwrite-p)))
+
+;;;###autoload (autoload 'bmkp-bmenu-edit-bookmark-name-and-location "bookmark+")
+(defun bmkp-bmenu-edit-bookmark-name-and-location (&optional internalp) ; Bound to `r' in bookmark list
+  "Edit the bookmark under the cursor: its name and location.
+With a prefix argument, edit the complete bookmark record (the
+internal, Lisp form)."
+  (interactive "P")
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bookmark-bmenu-ensure-position)
+  (let ((bmk-name  (bookmark-bmenu-bookmark)))
+    (if internalp
+        (bmkp-edit-bookmark-record bmk-name)
+      (let* ((new-data  (bmkp-edit-bookmark-name-and-location bmk-name))
+             (new-name  (car new-data)))
+        (if (not new-data) (message "No changes made") (bmkp-refresh-menu-list new-name))))))
+
+;;;###autoload (autoload 'bmkp-bmenu-edit-tags "bookmark+")
+(defun bmkp-bmenu-edit-tags ()          ; Bound to `T e' in bookmark list
+  "Edit the tags of the bookmark under the cursor.
+The edited value must be a list each of whose elements is either a
+string or a cons whose key is a string."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bookmark-bmenu-ensure-position)
+  (bmkp-edit-tags (bookmark-bmenu-bookmark)))
+
+;;;###autoload (autoload 'bmkp-bmenu-edit-bookmark-record "bookmark+")
+(defun bmkp-bmenu-edit-bookmark-record () ; Bound to `e' in bookmark list
+  "Edit the full record (the Lisp sexp) for the bookmark under the cursor.
+When you finish editing, use `\\[bmkp-edit-bookmark-record-send]'.
+The current bookmark list is then updated to reflect your edits."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bookmark-bmenu-ensure-position)
+  (bmkp-edit-bookmark-record (setq bmkp-edit-bookmark-orig-record  (bookmark-bmenu-bookmark))))
+
+;;;###autoload (autoload 'bmkp-bmenu-edit-marked "bookmark+")
+(defun bmkp-bmenu-edit-marked (&optional allp include-omitted-p) ; Bound to `E' in bookmark list
+  "Edit the full records (the Lisp sexps) of the marked bookmarks.
+If no bookmarks are marked then mark the bookmark on the current line,
+and edit its record.
+
+When you finish editing, use `\\[bmkp-edit-bookmark-records-send]'.
+The current bookmark list is then updated to reflect your edits.
+
+If no bookmark is marked, edit the bookmark of the current line.
+
+With a non-negative prefix arg, edit all bookmark records.
+
+Omitted bookmarks are excluded, by default.  With a negative prefix
+arg, any that are marked are included."
+  (interactive (list (and current-prefix-arg  (>= (prefix-numeric-value current-prefix-arg) 0))
+                     (and current-prefix-arg  (<  (prefix-numeric-value current-prefix-arg) 0))))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (setq bmkp-last-bmenu-bookmark  (bookmark-bmenu-bookmark))
+  ;; No marked bookmarks.  Mark this bookmark, so that `C-c C-c' in edit buffer will find it.
+  ;; Do this before we copy and strip full-bookmark property from name, because `bookmark-bmenu-mark'
+  ;; propertizes the name.
+  (unless bmkp-bmenu-marked-bookmarks (bookmark-bmenu-mark))
+  (let ((bufname      "*Edit Marked Bookmarks*")
+        (copied-bmks  (mapcar (lambda (bmk)
+                                (setq bmk  (copy-sequence bmk)) ; Shallow copy
+                                (let ((bname  (bmkp-bookmark-name-from-record bmk)))
+                                  ;; Strip properties from name.
+                                  (set-text-properties 0 (length bname) nil bname))
+                                bmk)
+                              (bmkp-bmenu-marked-or-this-or-all allp include-omitted-p))))
+    (unless copied-bmks (error "No marked bookmarks"))
+    (setq bmkp-edit-bookmark-records-number  (length copied-bmks))
+    (bmkp-with-output-to-plain-temp-buffer bufname
+     (princ (substitute-command-keys
+             (concat ";; Edit the Lisp records for the marked bookmarks.\n;;\n"
+                     ";; DO NOT CHANGE THE ORDER of the bookmarks in this buffer.\n"
+                     ";; DO NOT DELETE any of them.\n;;\n"
+                     ";; Type \\<bmkp-edit-bookmark-records-mode-map>\
+`\\[bmkp-edit-bookmark-records-send]' when done.\n;;\n")))
+     ;; $$$$$$ (let ((print-circle  t)) (pp copied-bmks)) ; $$$$$$ Should not really be needed now.
+     (pp copied-bmks)
+     (with-current-buffer bufname
+       (goto-char (point-min))
+       (buffer-enable-undo)))
+    (pop-to-buffer bufname)
+    (with-current-buffer (get-buffer bufname) (bmkp-edit-bookmark-records-mode))))
+
+(defun bmkp-bmenu-propertize-item (bookmark start end)
+  "Propertize text in buffer from START to END, indicating bookmark type.
+This propertizes the name of BOOKMARK.
+Also give this region the property `bmkp-bookmark-name' with as value
+the name of BOOKMARK as a propertized string.
+
+The propertized string has property `bmkp-full-record' with value
+BOOKMARK, which is the full bookmark record, with the string as its
+car.
+
+Return the propertized string (the bookmark name)."
+  (setq bookmark  (bmkp-get-bookmark bookmark))
+  (let* ((bookmark-name   (bmkp-bookmark-name-from-record bookmark))
+         (buffp           (bmkp-get-buffer-name bookmark))
+
+         (filep           (bookmark-get-filename bookmark))
+         (sudop           (and filep  (boundp 'tramp-file-name-regexp)
+                               (bmkp-string-match-p tramp-file-name-regexp filep)
+                               (bmkp-string-match-p bmkp-su-or-sudo-regexp filep))))
+    ;; Put the full bookmark itself on string `bookmark-name' as property `bmkp-full-record'.
+    ;; Then put that string on the name in the buffer text as property `bmkp-bookmark-name'.
+    (put-text-property 0 (length bookmark-name) 'bmkp-full-record bookmark bookmark-name)
+    (put-text-property start end 'bmkp-bookmark-name bookmark-name)
+    ;; Add faces, mouse face, and tooltips, to characterize the bookmark type.
+    (add-text-properties
+     start  end
+     (cond ((bookmark-prop-get bookmark 'file-handler) ; `file-handler' bookmark
+            (append (bmkp-face-prop 'bmkp-file-handler)
+                    '(mouse-face highlight follow-link t
+                      help-echo "mouse-2: Invoke the `file-handler' for this bookmark")))
+           ((bmkp-sequence-bookmark-p bookmark)                                     ; Sequence bookmark
+            (append (bmkp-face-prop 'bmkp-sequence)
+                    '(mouse-face highlight follow-link t
+                      help-echo "mouse-2: Invoke the bookmarks in this sequence")))
+           ((bmkp-function-bookmark-p bookmark)                                     ; Function bookmark
+            (append (bmkp-face-prop 'bmkp-function)
+                    '(mouse-face highlight follow-link t
+                      help-echo "mouse-2: Invoke this function bookmark")))
+           ((bmkp-variable-list-bookmark-p bookmark)                           ; Variable-list bookmark
+            (append (bmkp-face-prop 'bmkp-variable-list)
+                    '(mouse-face highlight follow-link t
+                      help-echo "mouse-2: Invoke this variable-list bookmark")))
+           ((bmkp-bookmark-list-bookmark-p bookmark)                           ; Bookmark-list bookmark
+            (append (bmkp-face-prop 'bmkp-bookmark-list)
+                    '(mouse-face highlight follow-link t
+                      help-echo "mouse-2: Invoke this bookmark-list bookmark")))
+           ((bmkp-snippet-bookmark-p bookmark)                                       ; Snippet bookmark
+            (append (bmkp-face-prop 'bmkp-snippet)
+                    '(mouse-face highlight follow-link t
+                      help-echo "mouse-2: Jump to this snippet bookmark")))
+           ((bmkp-desktop-bookmark-p bookmark)                                       ; Desktop bookmark
+            (append (bmkp-face-prop 'bmkp-desktop)
+                    '(mouse-face highlight follow-link t
+                      help-echo "mouse-2: Jump to this desktop bookmark")))
+           ((bmkp-bookmark-file-bookmark-p bookmark)                           ; Bookmark-file bookmark
+            (append (bmkp-face-prop 'bmkp-bookmark-file)
+                    '(mouse-face highlight follow-link t
+                      help-echo "mouse-2: Load this bookmark's bookmark file")))
+           ((bmkp-non-invokable-bookmark-p bookmark)                           ; Non-invokable bookmark
+            (append (bmkp-face-prop 'bmkp-no-jump)
+                    '(help-echo "You CANNOT JUMP to this bookmark")))
+           ((bmkp-icicles-search-hits-bookmark-p bookmark)               ; Icicles search hits bookmark
+            (append (bmkp-face-prop 'bmkp-no-jump)
+                    '(help-echo "You can use this only during Icicles search, NOT HERE")))
+           ((bmkp-info-bookmark-p bookmark)                                             ; Info bookmark
+            (append (bmkp-face-prop 'bmkp-info)
+                    '(mouse-face highlight follow-link t
+                      help-echo "mouse-2: Jump to this Info bookmark")))
+           ((bmkp-man-bookmark-p bookmark)                                               ; Man bookmark
+            (append (bmkp-face-prop 'bmkp-man)
+                    '(mouse-face highlight follow-link t
+                      help-echo (format "mouse-2 Goto `man' page"))))
+           ((bmkp-gnus-bookmark-p bookmark)                                             ; Gnus bookmark
+            (append (bmkp-face-prop 'bmkp-gnus)
+                    '(mouse-face highlight follow-link t
+                      help-echo "mouse-2: Jump to this Gnus bookmark")))
+           ((bmkp-url-bookmark-p bookmark)                                               ; URL bookmark
+            (append (bmkp-face-prop 'bmkp-url)
+                    `(mouse-face highlight follow-link t
+                      help-echo (format "mouse-2: Jump to URL `%s'" ,filep))))
+           ((and sudop  (not (bmkp-root-or-sudo-logged-p)))                   ; Root/sudo not logged in
+            (append (bmkp-face-prop 'bmkp-su-or-sudo)
+                    `(mouse-face highlight follow-link t
+                      help-echo (format "mouse-2: Jump to (visit) file `%s'" ,filep))))
+           ;; Test for remoteness before any other tests of the file itself
+           ;; (e.g. `file-exists-p'), so Tramp does not prompt for a password etc.
+           ((and filep  (bmkp-file-remote-p filep)  (not sudop)) ; Remote file (ssh, ftp)
+            (append (bmkp-face-prop 'bmkp-remote-file)
+                    `(mouse-face highlight follow-link t
+                      help-echo (format "mouse-2: Jump to (visit) remote file `%s'" ,filep))))
+           ((and filep                  ; Local directory or local Dired buffer (could be wildcards)
+                 (or (file-directory-p filep)  (bmkp-dired-bookmark-p bookmark)))
+            (append (bmkp-face-prop 'bmkp-local-directory)
+                    `(mouse-face highlight follow-link t
+                      help-echo (format "mouse-2: Dired directory `%s'" ,filep))))
+           ((and filep  (file-exists-p filep) ; Local file with region
+                 (bmkp-region-bookmark-p bookmark))
+            (append (bmkp-face-prop 'bmkp-local-file-with-region)
+                    `(mouse-face highlight follow-link t
+                      help-echo (format "mouse-2: Activate region in file `%s'" ,filep))))
+           ((and filep  (file-exists-p filep)) ; Local file without region
+            (append (bmkp-face-prop 'bmkp-local-file-without-region)
+                    `(mouse-face highlight follow-link t
+                      help-echo (format "mouse-2: Jump to (visit) file `%s'" ,filep))))
+           ; Existing buffer, including for a file bookmark if the file buffer has not yet been saved.
+           ((and buffp  (get-buffer buffp))
+            (append (bmkp-face-prop 'bmkp-buffer)
+                    `(mouse-face highlight follow-link t
+                      help-echo (format "mouse-2: Jump to buffer `%s'" ,buffp))))
+           ((or (not filep)  (equal filep bmkp-non-file-filename)) ; Non-file, and no existing buffer.
+            (append (bmkp-face-prop 'bmkp-non-file)
+                    `(mouse-face highlight follow-link t
+                      help-echo (format "mouse-2: Create buffer `%s' and jump to it" ,buffp))))
+           ((and filep  (not (file-exists-p filep))) ; Local-file bookmark, but no such file exists.
+            (bmkp-face-prop 'bmkp-no-local))
+           (t (append (bmkp-face-prop 'bmkp-bad-bookmark)
+                      `(mouse-face highlight follow-link t
+                        help-echo (format "BAD BOOKMARK (maybe): `%s'" ,filep))))))
+    bookmark-name))
+
+;;;###autoload (autoload 'bmkp-bmenu-quit "bookmark+")
+(defun bmkp-bmenu-quit ()               ; Bound to `q' in bookmark list
+  "Quit the bookmark list (aka \"menu list\").
+If `bmkp-bmenu-state-file' is non-nil, then save the state, to be
+restored the next time the bookmark list is shown.  Otherwise, reset
+the internal lists that record menu-list markings."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (if (not bmkp-bmenu-state-file)
+      (setq bmkp-bmenu-marked-bookmarks            ()
+            bmkp-bmenu-before-hide-marked-alist    ()
+            bmkp-bmenu-before-hide-unmarked-alist  ())
+    (when (interactive-p) (message "Saving bookmark-list display state..."))
+    (bmkp-save-menu-list-state)
+    (when (interactive-p) (message "Saving bookmark-list display state...done"))
+    (setq bmkp-bmenu-first-time-p  t))
+  (quit-window))
+
+(defun bmkp-bmenu-goto-bookmark-named (name)
+  "Go to the first bookmark whose name matches NAME (a string).
+If NAME has non-nil property `bmkp-full-record' then go to the
+bookmark it indicates.  Otherwise, just go to the first bookmark with
+the same name."
+  (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines)
+  (let ((full  (get-text-property 0 'bmkp-full-record name)))
+    (while (and (not (eobp))
+                (not (if full
+                         (equal full (get-text-property 0 'bmkp-full-record (bookmark-bmenu-bookmark)))
+                       (equal name (bookmark-bmenu-bookmark)))))
+      (forward-line 1)))
+  (bookmark-bmenu-ensure-position))     ; Just in case we fall off the end.
+
+;; This is a general function.  It is in this file because it is used only by the bmenu code.
+(defun bmkp-bmenu-barf-if-not-in-menu-list ()
+  "Raise an error if current buffer is not `*Bookmark List*'."
+  (unless (derived-mode-p 'bookmark-bmenu-mode)
+    (error "You can only use this command in buffer `*Bookmark List*'")))
+
+(defun bmkp-face-prop (value)
+  "Return a list with elements `face' or `font-lock-face' and VALUE.
+Starting with Emacs 22, the first element is `font-lock-face'."
+  (list (if (> emacs-major-version 21) 'font-lock-face 'face) value))
+
+(when (or (> emacs-major-version 24)    ; Emacs bug #12867 was partially fixed for Emacs 24.3+.
+          (and (= emacs-major-version 24)  (> emacs-minor-version 2)))
+  (defun bmkp-bmenu-mode-line-string ()
+    "Show, in mode line, information about the current bookmark-list display.
+The information includes the sort order and the number of marked,
+flagged (for deletion), tagged, temporary, annotated, and modified
+bookmarks currently shown.
+
+For each number indication:
+ If the current line has the indicator (e.g. mark, flag) and there are
+ others with the same indicator listed after it, then show `N/M',
+ where N is the number indicated through the current line and M is the
+ total number indicated."
+    (let* ((regexp->   "^>")
+           (regexp-D   "^D")
+           (regexp-t   "^.t")
+           (regexp-X   "^..X")
+           (regexp-a   "^..a")
+           (regexp-*   "^...\\*")
+           (nb->       (count-matches regexp-> (point-min) (point-max)))
+           (nb-D       (count-matches regexp-D (point-min) (point-max)))
+           (nb-t       (count-matches regexp-t (point-min) (point-max)))
+           (nb-X       (count-matches regexp-X (point-min) (point-max)))
+           (nb-a       (count-matches regexp-a (point-min) (point-max)))
+           (nb-*       (count-matches regexp-* (point-min) (point-max)))
+           (text-sort  (propertize
+                        (concat "sorting " (bmkp-sorting-description (bmkp-current-sort-order)))
+                        'face 'bmkp-heading))
+           regexp)
+      (let ((desc  "")
+            nb)
+        (dolist (mk  '(?> ?D ?t ?a ?X ?*))
+          (setq nb      (symbol-value (intern (format "nb-%c" mk)))
+                regexp  (symbol-value (intern (format "regexp-%c" mk)))
+                desc    (concat
+                         desc
+                         (and (> nb 0)
+                              (propertize
+                               (format
+                                "%s%d%c"
+                                (save-excursion
+                                  (forward-line 0)
+                                  (if (bmkp-looking-at-p (concat regexp ".*"))
+                                      (format "%d/" (1+ (count-matches regexp (point-min) (point))))
+                                    ""))
+                                nb  mk)
+                               'face (intern (format "bmkp-%c-mark" mk))))
+                         (and (> nb 0)  " "))))
+        (format "%s%s" desc text-sort))))
+
+  (defun bmkp-bmenu-mode-line ()        ; This works, but it shows the line number also.
+    "Set the mode line for buffer `*Bookmark List*'."
+    (condition-case nil
+        (progn
+          (set (make-local-variable 'mode-name) '(:eval (bmkp-bmenu-mode-line-string)))
+          ;; It seems that the line number must be present, and not invisible, for dynamic updating
+          ;; of the mode line when you move the cursor among lines.  Moving it way off to the right
+          ;; effectively gets rid of it (ugly hack).  See Emacs bug #12867.
+          (set (make-local-variable 'mode-line-position) '("%360l (line)")) ; Move it off the screen.
+          (set (make-local-variable 'mode-line-format)
+               '(("" mode-name "\t" mode-line-buffer-identification mode-line-position))))
+      (error nil))))
+
+(when (fboundp 'org-add-link-type)
+  (org-add-link-type "bookmark"           'bookmark-jump)
+  (org-add-link-type "bookmark-other-win" 'bookmark-jump-other-window)
+  (add-hook 'org-store-link-functions 'bmkp-bmenu-store-org-link 'APPEND)
+  (defun bmkp-bmenu-store-org-link ()
+    "Store a link to this bookmark for insertion in an Org-mode buffer.
+If you use a numeric prefix arg with `\\[org-store-link]' then the
+bookmark will be jumped to in the same window.  Without a numeric
+prefix arg, the link will use another window.  The link type is
+`bookmark' or `bookmark-other-win', respectively."
+    (require 'org)
+    (and (derived-mode-p 'bookmark-bmenu-mode)
+         (let* ((other-win  (and current-prefix-arg  (not (consp current-prefix-arg))))
+                (bmk        (bookmark-bmenu-bookmark))
+                (link       (format "bookmark%s:%s" (if other-win "-other-win" "") bmk))
+                (bmk-desc   (format "Bookmark: %s" bmk)))
+           (org-store-link-props :type "bookmark" :link link :description bmk-desc)))))
+
+
+;;(@* "Sorting - Commands")
+;;  *** Sorting - Commands ***
+
+;;;###autoload (autoload 'bmkp-bmenu-change-sort-order-repeat "bookmark+")
+(defun bmkp-bmenu-change-sort-order-repeat (arg) ; Bound to `s s'... in bookmark list
+  "Cycle to the next sort order.
+With a prefix arg, reverse current sort order.
+This is a repeatable version of `bmkp-bmenu-change-sort-order'."
+  (interactive "P")
+  (require 'repeat)
+  (bmkp-repeat-command 'bmkp-bmenu-change-sort-order))
+
+;;;###autoload (autoload 'bmkp-bmenu-change-sort-order "bookmark+")
+(defun bmkp-bmenu-change-sort-order (&optional arg)
+  "Cycle to the next sort order.
+With a prefix arg, reverse the current sort order."
+  (interactive "P")
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (setq bmkp-sort-orders-for-cycling-alist  (delq nil bmkp-sort-orders-for-cycling-alist))
+  (if arg
+      (bmkp-reverse-sort-order)
+    (let ((curr-bmk  (bookmark-bmenu-bookmark))
+          next-order)
+      (let ((orders  (mapcar #'car bmkp-sort-orders-for-cycling-alist)))
+        (setq next-order          (or (cadr (member (bmkp-current-sort-order) orders))  (car orders))
+              bmkp-sort-comparer  (cdr (assoc next-order bmkp-sort-orders-for-cycling-alist))))
+      (message "Sorting...")
+      (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P)
+      (when curr-bmk                 ; Put cursor back on the right line.
+        (bmkp-bmenu-goto-bookmark-named curr-bmk))
+      (when (interactive-p) (bmkp-msg-about-sort-order next-order)))))
+
+;; This is a general command.  It is in this file because it is used only by the bmenu code.
+;;;###autoload (autoload 'bmkp-reverse-sort-order "bookmark+")
+(defun bmkp-reverse-sort-order ()       ; Bound to `s r' in bookmark list
+  "Reverse the current bookmark sort order.
+If you combine this with \\<bookmark-bmenu-mode-map>\
+`\\[bmkp-reverse-multi-sort-order]', then see the doc for that command."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (setq bmkp-reverse-sort-p  (not bmkp-reverse-sort-p))
+  (let ((curr-bmk  (bookmark-bmenu-bookmark)))
+    (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P)
+    (when curr-bmk                   ; Put cursor back on the right line.
+      (bmkp-bmenu-goto-bookmark-named curr-bmk)))
+  (when (interactive-p) (bmkp-msg-about-sort-order (bmkp-current-sort-order))))
+
+;; This is a general command.  It is in this file because it is used only by the bmenu code.
+;;;###autoload (autoload 'bmkp-reverse-multi-sort-order "bookmark+")
+(defun bmkp-reverse-multi-sort-order () ; Bound to `s C-r' in bookmark list
+  "Reverse the application of multi-sorting predicates.
+These are the PRED predicates described for option
+`bmkp-sort-comparer'.
+
+This reverses the order in which the predicates are tried, and it
+also complements the truth value returned by each predicate.
+
+For example, if the list of multi-sorting predicates is (p1 p2 p3),
+then the predicates are tried in the order: p3, p2, p1.  And if a
+predicate returns true, `(t)', then the effect is as if it returned
+false, `(nil)', and vice versa.
+
+The use of multi-sorting predicates tends to group bookmarks, with the
+first predicate corresponding to the first bookmark group etc.
+
+The effect of \\<bookmark-bmenu-mode-map>`\\[bmkp-reverse-multi-sort-order]' is \
+roughly as follows:
+
+ - without also `\\[bmkp-reverse-sort-order]', it reverses the bookmark order in each \
+group
+
+ - combined with `\\[bmkp-reverse-sort-order]', it reverses the order of the bookmark
+   groups, but not the bookmarks within a group
+
+This is a rough description.  The actual behavior can be complex,
+because of how each predicate is defined.  If this description helps
+you, fine.  If not, just experiment and see what happens. \;-)
+
+Remember that ordinary `\\[bmkp-reverse-sort-order]' reversal on its own is \
+straightforward.
+If you find `\\[bmkp-reverse-multi-sort-order]' confusing or not helpful, then do not \
+use it."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (setq bmkp-reverse-multi-sort-p  (not bmkp-reverse-multi-sort-p))
+  (let ((curr-bmk  (bookmark-bmenu-bookmark)))
+    (bookmark-bmenu-surreptitiously-rebuild-list 'NO-MSG-P)
+    (when curr-bmk                   ; Put cursor back on the right line.
+      (bmkp-bmenu-goto-bookmark-named curr-bmk)))
+  (when (interactive-p) (bmkp-msg-about-sort-order (bmkp-current-sort-order))))
+
+
+
+;; The ORDER of the macro calls here defines the REVERSE ORDER of
+;; `bmkp-sort-orders-alist'.  The first here is thus also the DEFAULT sort order.
+;; Entries are traversed by `s s'..., in `bmkp-sort-orders-alist' order.
+
+(bmkp-define-sort-command               ; Bound to `s k' in bookmark list (`k' for "kind")
+ "by bookmark type"                     ; `bmkp-bmenu-sort-by-bookmark-type'
+ ((bmkp-info-node-name-cp bmkp-url-cp bmkp-gnus-cp bmkp-local-file-type-cp bmkp-handler-cp)
+  bmkp-alpha-p)
+ "Sort bookmarks by type: Info, URL, Gnus, files, other (by handler name).")
+
+(bmkp-define-sort-command               ; Bound to `s u' in bookmark list
+ "by url"                           ; `bmkp-bmenu-sort-by-url'
+ ((bmkp-url-cp) bmkp-alpha-p)
+ "Sort URL bookmarks alphabetically by their URL/filename.
+When two bookmarks are not comparable this way, compare them by
+bookmark name.")
+
+;; $$$$$$ Not used now.
+;; (bmkp-define-sort-command               ; Bound to `s w 3' in bookmark list
+;;  "by W3M url"                           ; `bmkp-bmenu-sort-by-w3m-url'
+;;  ((bmkp-w3m-cp) bmkp-alpha-p)
+;;  "Sort W3M bookmarks alphabetically by their URL/filename.
+;; When two bookmarks are not comparable this way, compare them by
+;; bookmark name.")
+
+;; (when (fboundp 'bmkp-eww-cp)
+;;   ;; $$$$$$ Not used now.
+;;   ;; (bmkp-define-sort-command               ; Bound to `s w e' in bookmark list
+;;   ;;  "by EWW url"                           ; `bmkp-bmenu-sort-by-w3m-url'
+;;   ;;  ((bmkp-eww-cp) bmkp-alpha-p)
+;;   ;;  "Sort EWW bookmarks alphabetically by their URL/filename.
+;;   ;; When two bookmarks are not comparable this way, compare them by
+;;   ;; bookmark name.")
+;;   )
+
+(bmkp-define-sort-command               ; Bound to `s g' in bookmark list
+ "by Gnus thread"                       ; `bmkp-bmenu-sort-by-Gnus-thread'
+ ((bmkp-gnus-cp) bmkp-alpha-p)
+ "Sort Gnus bookmarks by group, then by article, then by message.
+When two bookmarks are not comparable this way, compare them by
+bookmark name.")
+
+(bmkp-define-sort-command               ; Bound to `s i' in bookmark list
+ "by Info node name"                    ; `bmkp-bmenu-sort-by-Info-node-name'
+ ((bmkp-info-node-name-cp) bmkp-alpha-p)
+ "Sort Info bookmarks by manual (file) name, then node name, then position.
+When two bookmarks are not comparable this way, compare them by
+bookmark name.")
+
+(bmkp-define-sort-command               ; Bound to `s I' in bookmark list
+ "by Info position"                     ; `bmkp-bmenu-sort-by-Info-position'
+ ((bmkp-info-position-cp) bmkp-alpha-p)
+ "Sort Info bookmarks by manual (file) name, then position (order in book).
+When two bookmarks are not comparable this way, compare them by
+bookmark name.")
+
+(bmkp-define-sort-command               ; Bound to `s f u' in bookmark list
+ "by last local file update"            ; `bmkp-bmenu-sort-by-last-local-file-update'
+ ((bmkp-local-file-updated-more-recently-cp) bmkp-alpha-p)
+ "Sort bookmarks by last local file update time.
+Sort a local file before a remote file, and a remote file before other
+bookmarks.  Otherwise, sort by bookmark name.")
+
+(bmkp-define-sort-command               ; Bound to `s f d' in bookmark list
+ "by last local file access"            ; `bmkp-bmenu-sort-by-last-local-file-access'
+ ((bmkp-local-file-accessed-more-recently-cp) bmkp-alpha-p)
+ "Sort bookmarks by last local file access time.
+A local file sorts before a remote file, which sorts before other
+bookmarks.  Otherwise, sort by bookmark name.")
+
+(bmkp-define-sort-command               ; Bound to `s f s' in bookmark list
+ "by local file size"                   ; `bmkp-bmenu-sort-by-local-file-size'
+ ((bmkp-local-file-size-cp) bmkp-alpha-p)
+ "Sort bookmarks by local file size.
+A local file sorts before a remote file, which sorts before other
+bookmarks.  Otherwise, sort by bookmark name.")
+
+(bmkp-define-sort-command               ; Bound to `s f n' in bookmark list
+ "by file name"                         ; `bmkp-bmenu-sort-by-file-name'
+ ((bmkp-file-alpha-cp) bmkp-alpha-p)
+ "Sort bookmarks by file name.
+When two bookmarks are not comparable by file name, compare them by
+bookmark name.")
+
+(bmkp-define-sort-command               ; Bound to `s f k' in bookmark list (`k' for "kind")
+ "by local file type"                   ; `bmkp-bmenu-sort-by-local-file-type'
+ ((bmkp-local-file-type-cp) bmkp-alpha-p)
+ "Sort bookmarks by local file type: file, symlink, directory.
+A local file sorts before a remote file, which sorts before other
+bookmarks.  Otherwise, sort by bookmark name.")
+
+(bmkp-define-sort-command               ; Bound to `s D' in bookmark list
+ "flagged before unflagged"             ; `bmkp-bmenu-sort-flagged-before-unflagged'
+ ((bmkp-flagged-cp) bmkp-alpha-p)
+ "Sort bookmarks by putting flagged for deletion before unflagged.
+Otherwise alphabetize by bookmark name.")
+
+(bmkp-define-sort-command               ; Bound to `s *' in bookmark list
+ "modified before unmodified"           ; `bmkp-bmenu-sort-modified-before-unmodified'
+ ((bmkp-modified-cp) bmkp-alpha-p)
+ "Sort bookmarks by putting modified before unmodified (saved).
+Otherwise alphabetize by bookmark name.")
+
+(bmkp-define-sort-command               ; Bound to `s >' in bookmark list
+ "marked before unmarked"               ; `bmkp-bmenu-sort-marked-before-unmarked'
+ ((bmkp-marked-cp) bmkp-alpha-p)
+ "Sort bookmarks by putting marked before unmarked.
+Otherwise alphabetize by bookmark name.")
+
+(bmkp-define-sort-command               ; Bound to `s 0' (zero) in bookmark list
+ "by creation time"                     ; `bmkp-bmenu-sort-by-creation-time'
+ ((bmkp-bookmark-creation-cp) bmkp-alpha-p)
+ "Sort bookmarks by the time of their creation.
+When one or both of the bookmarks does not have a `created' entry),
+compare them by bookmark name.")
+
+(bmkp-define-sort-command               ; Bound to `s a' in bookmark list
+ "annotated before unannotated" ; `bmkp-bmenu-sort-annotated-before-unannotated'
+ ((bmkp-annotated-cp) bmkp-alpha-p)
+ "Sort bookmarks by putting annotated before unannotated.
+Otherwise alphabetize by bookmark name.")
+
+(bmkp-define-sort-command               ; Bound to `s b' in bookmark list
+ "by last buffer or file access"        ; `bmkp-bmenu-sort-by-last-buffer-or-file-access'
+ ((bmkp-buffer-last-access-cp bmkp-local-file-accessed-more-recently-cp)
+  bmkp-alpha-p)
+ "Sort bookmarks by last buffer access or last local file access.
+Sort a bookmark accessed more recently before one accessed less
+recently or not accessed.  Sort a bookmark to an existing buffer
+before a local file bookmark.  When two bookmarks are not comparable
+by such critera, sort them by bookmark name.  (In particular, sort
+remote-file bookmarks by bookmark name.")
+
+(bmkp-define-sort-command               ; Bound to `s v' in bookmark list
+ "by bookmark visit frequency"          ; `bmkp-bmenu-sort-by-bookmark-visit-frequency'
+ ((bmkp-visited-more-cp) bmkp-alpha-p)
+ "Sort bookmarks by the number of times they were visited as bookmarks.
+When two bookmarks are not comparable by visit frequency, compare them
+by bookmark name.")
+
+(bmkp-define-sort-command               ; Bound to `s d' in bookmark list
+ "by last bookmark access"              ; `bmkp-bmenu-sort-by-last-bookmark-access'
+ ((bmkp-bookmark-last-access-cp) bmkp-alpha-p)
+ "Sort bookmarks by the time of their last visit as bookmarks.
+When two bookmarks are not comparable by visit time, compare them
+by bookmark name.")
+
+(bmkp-define-sort-command               ; Bound to `s n' in bookmark list
+ "by bookmark name"                     ; `bmkp-bmenu-sort-by-bookmark-name'
+ bmkp-alpha-p
+ "Sort bookmarks by bookmark name, respecting `case-fold-search'.")
+
+(bmkp-define-sort-command               ; Bound to `s t' in bookmark list
+ "tagged before untagged"               ; `bmkp-bmenu-sort-tagged-before-untagged'
+ ((bmkp-tagged-cp) bmkp-alpha-p)
+ "Sort bookmarks by putting tagged before untagged.
+Otherwise alphabetize by bookmark name.")
+
+;; This is a general option.  It is in this file because it is used mainly by the bmenu code.
+;; Its definitions MUST COME AFTER the calls to macro `bmkp-define-sort-command'.
+;; Otherwise, they won't pick up a populated `bmkp-sort-orders-alist'.
+(when (> emacs-major-version 20)
+  (defcustom bmkp-sort-orders-for-cycling-alist (copy-sequence bmkp-sort-orders-alist)
+    "*Alist of sort orders used for cycling via `s s'...
+This is a subset of the complete list of available sort orders,
+`bmkp-sort-orders-alist'.  This lets you cycle among fewer sort
+orders, if there are some that you do not use often.
+
+See the doc for `bmkp-sort-orders-alist', for the structure of
+this value."
+    :type '(alist
+            :key-type (choice :tag "Sort order" string symbol)
+            :value-type (choice
+                         (const :tag "None (do not sort)" nil)
+                         (function :tag "Sorting Predicate")
+                         (list :tag "Sorting Multi-Predicate"
+                          (repeat (function :tag "Component Predicate"))
+                          (choice
+                           (const :tag "None" nil)
+                           (function :tag "Final Predicate")))))
+    :group 'bookmark-plus))
+
+(unless (> emacs-major-version 20)      ; Emacs 20: custom type `alist' doesn't exist.
+  (defcustom bmkp-sort-orders-for-cycling-alist (copy-sequence bmkp-sort-orders-alist)
+    "*Alist of sort orders used for cycling via `s s'...
+This is a subset of the complete list of available sort orders,
+`bmkp-sort-orders-alist'.  This lets you cycle among fewer sort
+orders, if there are some that you do not use often.
+
+See the doc for `bmkp-sort-orders-alist', for the structure of this
+value."
+    :type '(repeat
+            (cons
+             (choice :tag "Sort order" string symbol)
+             (choice
+              (const :tag "None (do not sort)" nil)
+              (function :tag "Sorting Predicate")
+              (list :tag "Sorting Multi-Predicate"
+               (repeat (function :tag "Component Predicate"))
+               (choice
+                (const :tag "None" nil)
+                (function :tag "Final Predicate"))))))
+    :group 'bookmark-plus))
+
+
+;;(@* "Other Bookmark+ Functions (`bmkp-*')")
+;;  *** Other Bookmark+ Functions (`bmkp-*') ***
+
+;;;###autoload (autoload 'bmkp-bmenu-show-this-annotation+move-down "bookmark+")
+(defun bmkp-bmenu-show-this-annotation+move-down (&optional n) ; Bound to `M-down' in bookmark list
+  "Move down N lines in bookmark-list display and show annotation, if any."
+  (interactive "p")
+  (bmkp-bmenu-kill-annotation)
+  (forward-line n)
+  (bookmark-bmenu-show-annotation 'MSGP))
+
+;;;###autoload (autoload 'bmkp-bmenu-show-this-annotation+move-up "bookmark+")
+(defun bmkp-bmenu-show-this-annotation+move-up (&optional n) ; Bound to `M-up' in bookmark list
+  "Move up N lines in bookmark-list display and show annotation, if any."
+  (interactive "p")
+  (bmkp-bmenu-kill-annotation)
+  (forward-line (- n))
+  (bookmark-bmenu-show-annotation 'MSGP))
+
+(defun bmkp-bmenu-kill-annotation (&optional bookmark-name)
+  "Kill annotation buffer, if any, for BOOKMARK-NAME.
+If BOOKMARK-NAME is nil, use the bookmark of the current line.
+Return non-nil only if there was such an annotation buffer."
+  (let ((ann-buf  (get-buffer (format "*`%s' Annotation*"
+                                      (or bookmark-name  (bookmark-bmenu-bookmark))))))
+    (when ann-buf (kill-buffer ann-buf))))
+
+;;;###autoload (autoload 'bmkp-bmenu-describe-this+move-down "bookmark+")
+(defun bmkp-bmenu-describe-this+move-down (&optional defn) ; Bound to `C-down' in bookmark list
+  "Move to next line in bookmark-list display and describe the bookmark.
+With a prefix argument, show the internal definition of the bookmark."
+  (interactive "P")
+  (forward-line 1)
+  (bmkp-bmenu-describe-this-bookmark))
+
+;;;###autoload (autoload 'bmkp-bmenu-describe-this+move-up "bookmark+")
+(defun bmkp-bmenu-describe-this+move-up (&optional defn) ; Bound to `C-up' in bookmark list
+  "Move to previous line in bookmark-list display and describe the bookmark.
+With a prefix argument, show the internal definition of the bookmark."
+  (interactive "P")
+  (forward-line -1)
+  (bmkp-bmenu-describe-this-bookmark))
+
+;;;###autoload (autoload 'bmkp-bmenu-describe-this-bookmark "bookmark+")
+(defun bmkp-bmenu-describe-this-bookmark (&optional defn) ; Bound to `C-h RET' in bookmark list
+  "Describe bookmark of current line.
+With a prefix argument, show the internal definition of the bookmark."
+  (interactive "P")
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (save-selected-window (if defn
+                            (bmkp-describe-bookmark-internals (bookmark-bmenu-bookmark))
+                          (bmkp-describe-bookmark (bookmark-bmenu-bookmark)))))
+
+;;;###autoload (autoload 'bmkp-bmenu-describe-marked "bookmark+")
+(defun bmkp-bmenu-describe-marked (&optional defn include-omitted-p) ; Bound to `C-h >' in bookmark list
+  "Describe the marked bookmarks, in the current sort order.
+If no bookmark is marked, act on the bookmark of the current line.
+
+With a non-negative prefix argument, show the internal definitions.
+
+Omitted bookmarks are excluded, by default.  With a non-positive
+prefix arg, any that are marked are included."
+  (interactive (list (and current-prefix-arg  (>= (prefix-numeric-value current-prefix-arg) 0))
+                     (and current-prefix-arg  (<= (prefix-numeric-value current-prefix-arg) 0))))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (help-setup-xref (list #'bmkp-bmenu-describe-marked) (interactive-p))
+  (bmkp-with-help-window "*Help*"
+    (dolist (bmk  (bmkp-sort-omit (bmkp-bmenu-marked-or-this-or-all nil include-omitted-p)))
+      (if defn
+          (let* ((bname         (bmkp-bookmark-name-from-record bmk))
+                 (print-circle  bmkp-propertize-bookmark-names-flag) ; For `pp-to-string'
+                 (print-gensym  bmkp-propertize-bookmark-names-flag) ; For `pp-to-string'
+                 (print-length  nil)    ; For `pp-to-string'
+                 (print-level   nil)    ; For `pp-to-string'
+                 (help-text     (format "%s\n%s\n\n%s"
+                                        bname (make-string (length bname) ?-) (pp-to-string bmk))))
+            (princ help-text) (terpri))
+        (princ (bmkp-bookmark-description bmk)) (terpri)))))
+
+(defun bmkp-bmenu-get-marked-files ()
+  "Return a list of the file names of the marked bookmarks.
+Marked bookmarks that have no associated file are ignored."
+  (let ((files  ()))
+    (dolist (bmk  bmkp-bmenu-marked-bookmarks)
+      (when (bmkp-file-bookmark-p bmk) (push (bookmark-get-filename bmk) files)))
+    files))
+
+(defun bmkp-bmenu-marked-or-this-or-all (&optional allp include-omitted-p)
+  "Return the marked bookmarks or the current-line bookmark if none marked.
+Non-nil ALLP means return all bookmarks: `bookmark-alist'.
+Do not include marked bookmarks that are omitted, unless optional arg
+INCLUDE-OMITTED-P is non-nil.  INCLUDE-OMITTED-P has no effect if none
+are marked or ALLP is non-nil."
+  (if allp
+      bookmark-alist
+    (or (if include-omitted-p
+            (bmkp-marked-bookmarks-only)
+          (bmkp-remove-if #'bmkp-omitted-bookmark-p (bmkp-marked-bookmarks-only)))
+        (and (bookmark-bmenu-bookmark)  (list (bmkp-get-bookmark (bookmark-bmenu-bookmark)))))))
+ 
+;;(@* "Keymaps")
+;;; Keymaps ----------------------------------------------------------
+
+;; `bookmark-bmenu-mode-map'
+
+(when (< emacs-major-version 21)
+  (define-key bookmark-bmenu-mode-map (kbd "RET")          'bookmark-bmenu-this-window))
+(define-key bookmark-bmenu-mode-map "\M-~"                 'bmkp-toggle-saving-bookmark-file)
+(define-key bookmark-bmenu-mode-map (kbd "C-M-~")          'bmkp-toggle-saving-menu-list-state)
+(define-key bookmark-bmenu-mode-map "."                    'bmkp-bmenu-show-all)
+(define-key bookmark-bmenu-mode-map ">"                    'bmkp-bmenu-toggle-show-only-marked)
+(define-key bookmark-bmenu-mode-map "<"                    'bmkp-bmenu-toggle-show-only-unmarked)
+(define-key bookmark-bmenu-mode-map (kbd "M-<DEL>")        'bmkp-bmenu-unmark-all)
+(define-key bookmark-bmenu-mode-map "-"                    nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "->"                   'bmkp-bmenu-omit/unomit-marked)
+(define-key bookmark-bmenu-mode-map "-S"                   'bmkp-bmenu-show-only-omitted-bookmarks)
+(define-key bookmark-bmenu-mode-map "-U"                   'bmkp-unomit-all)
+(define-key bookmark-bmenu-mode-map "="                    nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "=bM"                  'bmkp-bmenu-mark-specific-buffer-bookmarks)
+(define-key bookmark-bmenu-mode-map "=fM"                  'bmkp-bmenu-mark-specific-file-bookmarks)
+(define-key bookmark-bmenu-mode-map "=bS"                  'bmkp-bmenu-show-only-specific-buffer-bookmarks)
+(define-key bookmark-bmenu-mode-map "=fS"                  'bmkp-bmenu-show-only-specific-file-bookmarks)
+(define-key bookmark-bmenu-mode-map "%"                    nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "%m"                   'bmkp-bmenu-regexp-mark)
+(define-key bookmark-bmenu-mode-map "*"                    nil) ; For Emacs 20
+(when (< emacs-major-version 21)
+  (define-key bookmark-bmenu-mode-map "*m"                 'bookmark-bmenu-mark))
+(define-key bookmark-bmenu-mode-map "#"                    nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "#M"                   'bmkp-bmenu-mark-autonamed-bookmarks)
+(define-key bookmark-bmenu-mode-map "#S"                   'bmkp-bmenu-show-only-autonamed-bookmarks)
+;; `a' is `bookmark-bmenu-show-annotation' in vanilla Emacs.
+;; `A' is `bookmark-bmenu-show-all-annotations' in vanilla Emacs.
+;; `e' is `bookmark-bmenu-edit-annotation' in vanilla Emacs.
+(define-key bookmark-bmenu-mode-map "a"                    nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "aa"                   'bookmark-bmenu-show-annotation)
+(define-key bookmark-bmenu-mode-map "aA"                   'bookmark-bmenu-show-all-annotations)
+(define-key bookmark-bmenu-mode-map "ae"                   'bookmark-bmenu-edit-annotation)
+(define-key bookmark-bmenu-mode-map "a>"                   'bmkp-bmenu-edit-annotations-for-marked)
+(define-key bookmark-bmenu-mode-map "A"                    nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "AM"                   'bmkp-bmenu-mark-autofile-bookmarks)
+(define-key bookmark-bmenu-mode-map "AS"                   'bmkp-bmenu-show-only-autofile-bookmarks)
+(define-key bookmark-bmenu-mode-map "B"                    nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "BM"                   'bmkp-bmenu-mark-non-file-bookmarks)
+(define-key bookmark-bmenu-mode-map "BS"                   'bmkp-bmenu-show-only-non-file-bookmarks)
+(define-key bookmark-bmenu-mode-map (kbd "M-n")            'bmkp-bmenu-clone-bookmark)
+(define-key bookmark-bmenu-mode-map (kbd "C-c C-c")        'bmkp-bmenu-define-command)
+(define-key bookmark-bmenu-mode-map (kbd "C-c C-S-c")      'bmkp-bmenu-define-full-snapshot-command)
+(define-key bookmark-bmenu-mode-map (kbd "C-c C-j")        'bmkp-bmenu-define-jump-marked-command)
+(define-key bookmark-bmenu-mode-map "d"                    'bmkp-bmenu-flag-for-deletion)
+(define-key bookmark-bmenu-mode-map "D"                    'bmkp-bmenu-delete-marked)
+(define-key bookmark-bmenu-mode-map "\C-d"                 'bmkp-bmenu-flag-for-deletion-backwards)
+(define-key bookmark-bmenu-mode-map "\M-d"                 nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "\M-d>"                'bmkp-bmenu-dired-marked)
+(define-key bookmark-bmenu-mode-map "\M-d\M-m"             'bmkp-bmenu-mark-dired-bookmarks)
+(define-key bookmark-bmenu-mode-map "\M-d\M-s"             'bmkp-bmenu-show-only-dired-bookmarks)
+;; `e' is `bookmark-bmenu-edit-annotation' in vanilla Emacs.
+(define-key bookmark-bmenu-mode-map "e"                    'bmkp-bmenu-edit-bookmark-record)
+(define-key bookmark-bmenu-mode-map "E"                    'bmkp-bmenu-edit-marked)
+(define-key bookmark-bmenu-mode-map "F"                    nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "FM"                   'bmkp-bmenu-mark-file-bookmarks)
+(define-key bookmark-bmenu-mode-map "FS"                   'bmkp-bmenu-show-only-file-bookmarks)
+(define-key bookmark-bmenu-mode-map "g"                    'bmkp-bmenu-refresh-menu-list)
+(define-key bookmark-bmenu-mode-map "G"                    nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "GM"                   'bmkp-bmenu-mark-gnus-bookmarks)
+(define-key bookmark-bmenu-mode-map "GS"                   'bmkp-bmenu-show-only-gnus-bookmarks)
+(if (fboundp 'command-remapping)
+    (define-key bookmark-bmenu-mode-map [remap describe-mode] 'bmkp-bmenu-mode-status-help)
+  ;; In Emacs < 22, the `substitute-...' affects only `?', not `C-h m', so we add it separately.
+  (substitute-key-definition 'describe-mode 'bmkp-bmenu-mode-status-help bookmark-bmenu-mode-map)
+  (define-key bookmark-bmenu-mode-map "\C-hm"              'bmkp-bmenu-mode-status-help))
+(define-key bookmark-bmenu-mode-map (kbd "C-h >")          'bmkp-bmenu-describe-marked)
+(define-key bookmark-bmenu-mode-map (kbd "C-h RET")        'bmkp-bmenu-describe-this-bookmark)
+(define-key bookmark-bmenu-mode-map (kbd "C-h C-<return>") 'bmkp-bmenu-describe-this-bookmark)
+(define-key bookmark-bmenu-mode-map (kbd "C-<down>")       'bmkp-bmenu-describe-this+move-down)
+(define-key bookmark-bmenu-mode-map (kbd "C-<up>")         'bmkp-bmenu-describe-this+move-up)
+(define-key bookmark-bmenu-mode-map (kbd "M-<down>")       'bmkp-bmenu-show-this-annotation+move-down)
+(define-key bookmark-bmenu-mode-map (kbd "M-<up>")         'bmkp-bmenu-show-this-annotation+move-up)
+(define-key bookmark-bmenu-mode-map (kbd "M-<return>")     'bmkp-bmenu-w32-open)
+(define-key bookmark-bmenu-mode-map [M-mouse-2]            'bmkp-bmenu-w32-open-with-mouse)
+(when (featurep 'bookmark+-lit)
+  (define-key bookmark-bmenu-mode-map "H"                  nil) ; For Emacs 20
+  (define-key bookmark-bmenu-mode-map "H+"                 'bmkp-bmenu-set-lighting)
+  (define-key bookmark-bmenu-mode-map "H>+"                'bmkp-bmenu-set-lighting-for-marked)
+  (define-key bookmark-bmenu-mode-map "H>H"                'bmkp-bmenu-light-marked)
+  (define-key bookmark-bmenu-mode-map "HH"                 'bmkp-bmenu-light)
+  (define-key bookmark-bmenu-mode-map "HM"                 'bmkp-bmenu-mark-lighted-bookmarks)
+  (define-key bookmark-bmenu-mode-map "HS"                 'bmkp-bmenu-show-only-lighted-bookmarks)
+  (define-key bookmark-bmenu-mode-map "H>U"                'bmkp-bmenu-unlight-marked)
+  (define-key bookmark-bmenu-mode-map "HU"                 'bmkp-bmenu-unlight))
+(define-key bookmark-bmenu-mode-map "i"                    nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "iM"                  'bmkp-bmenu-mark-icicles-search-hits-bookmarks)
+(define-key bookmark-bmenu-mode-map "iS"                'bmkp-bmenu-show-only-icicles-search-hits-bookmarks)
+(define-key bookmark-bmenu-mode-map "I"                    nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "IM"                   'bmkp-bmenu-mark-info-bookmarks)
+(define-key bookmark-bmenu-mode-map "IS"                   'bmkp-bmenu-show-only-info-bookmarks)
+(define-key bookmark-bmenu-mode-map "\M-I"                 nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "\M-I\M-M"             'bmkp-bmenu-mark-image-bookmarks)
+(define-key bookmark-bmenu-mode-map "\M-I\M-S"             'bmkp-bmenu-show-only-image-bookmarks)
+
+;; Prefix `j' and `J' bindings are made in `bookmark+-key.el', by binding `bmkp-jump(-other-window)-map'.
+
+(define-key bookmark-bmenu-mode-map "k"                    'bmkp-bmenu-flag-for-deletion)
+(define-key bookmark-bmenu-mode-map "K"                    nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "KM"                   'bmkp-bmenu-mark-desktop-bookmarks)
+(define-key bookmark-bmenu-mode-map "KS"                   'bmkp-bmenu-show-only-desktop-bookmarks)
+(define-key bookmark-bmenu-mode-map "L"                    'bmkp-switch-bookmark-file-create)
+(define-key bookmark-bmenu-mode-map [(control shift ?l)]   'bookmark-bmenu-locate) ; `C-L' (aka `C-S-l')
+(define-key bookmark-bmenu-mode-map "\M-l"                 'bmkp-bmenu-load-marked-bookmark-file-bookmarks)
+(define-key bookmark-bmenu-mode-map "\M-L"                 'bmkp-temporary-bookmarking-mode)
+(define-key bookmark-bmenu-mode-map "M"                    nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "MM"                   'bmkp-bmenu-mark-man-bookmarks)
+(define-key bookmark-bmenu-mode-map "MS"                   'bmkp-bmenu-show-only-man-bookmarks)
+(define-key bookmark-bmenu-mode-map "\M-m"                 'bmkp-bmenu-mark-all)
+(define-key bookmark-bmenu-mode-map "N"                    nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "NM"                   'bmkp-bmenu-mark-non-invokable-bookmarks)
+(define-key bookmark-bmenu-mode-map "NS"                   'bmkp-bmenu-show-only-non-invokable-bookmarks)
+(define-key bookmark-bmenu-mode-map "O"                    nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "OM"                 'bmkp-bmenu-mark-orphaned-local-file-bookmarks)
+(define-key bookmark-bmenu-mode-map "OS"                'bmkp-bmenu-show-only-orphaned-local-file-bookmarks)
+(define-key bookmark-bmenu-mode-map "P"                    nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "PA"                  'bmkp-bmenu-filter-annotation-incrementally)
+(define-key bookmark-bmenu-mode-map "PB"                 'bmkp-bmenu-filter-bookmark-name-incrementally)
+(define-key bookmark-bmenu-mode-map "PF"                   'bmkp-bmenu-filter-file-name-incrementally)
+(define-key bookmark-bmenu-mode-map "PT"                   'bmkp-bmenu-filter-tags-incrementally)
+(define-key bookmark-bmenu-mode-map "q"                    'bmkp-bmenu-quit)
+(define-key bookmark-bmenu-mode-map "\M-q"                'bmkp-bmenu-query-replace-marked-bookmarks-regexp)
+(define-key bookmark-bmenu-mode-map "Q"                    nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "QM"                   'bmkp-bmenu-mark-function-bookmarks)
+(define-key bookmark-bmenu-mode-map "QS"                   'bmkp-bmenu-show-only-function-bookmarks)
+(define-key bookmark-bmenu-mode-map "r"                    'bmkp-bmenu-edit-bookmark-name-and-location)
+(define-key bookmark-bmenu-mode-map "R"                    nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "RM"                   'bmkp-bmenu-mark-region-bookmarks)
+(define-key bookmark-bmenu-mode-map "RS"                   'bmkp-bmenu-show-only-region-bookmarks)
+(define-key bookmark-bmenu-mode-map "\M-r"                 'bookmark-bmenu-relocate) ; `R' in Emacs
+(define-key bookmark-bmenu-mode-map "\M-R"                 'bmkp-bmenu-relocate-marked)
+(define-key bookmark-bmenu-mode-map "S"                    'bookmark-bmenu-save) ; `s' in Emacs
+(define-key bookmark-bmenu-mode-map "s"                    nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "s>"                   'bmkp-bmenu-sort-marked-before-unmarked)
+(define-key bookmark-bmenu-mode-map "s*"                   'bmkp-bmenu-sort-modified-before-unmodified)
+(define-key bookmark-bmenu-mode-map "s0"                   'bmkp-bmenu-sort-by-creation-time)
+(define-key bookmark-bmenu-mode-map "sa"                   'bmkp-bmenu-sort-annotated-before-unannotated)
+(define-key bookmark-bmenu-mode-map "sb"                   'bmkp-bmenu-sort-by-last-buffer-or-file-access)
+(define-key bookmark-bmenu-mode-map "sd"                   'bmkp-bmenu-sort-by-last-bookmark-access)
+(define-key bookmark-bmenu-mode-map "sD"                   'bmkp-bmenu-sort-flagged-before-unflagged)
+(define-key bookmark-bmenu-mode-map "sfd"                  'bmkp-bmenu-sort-by-last-local-file-access)
+(define-key bookmark-bmenu-mode-map "sfk"                  'bmkp-bmenu-sort-by-local-file-type)
+(define-key bookmark-bmenu-mode-map "sfn"                  'bmkp-bmenu-sort-by-file-name)
+(define-key bookmark-bmenu-mode-map "sfs"                  'bmkp-bmenu-sort-by-local-file-size)
+(define-key bookmark-bmenu-mode-map "sfu"                  'bmkp-bmenu-sort-by-last-local-file-update)
+(define-key bookmark-bmenu-mode-map "sg"                   'bmkp-bmenu-sort-by-Gnus-thread)
+(define-key bookmark-bmenu-mode-map "si"                   'bmkp-bmenu-sort-by-Info-node-name)
+(define-key bookmark-bmenu-mode-map "sI"                   'bmkp-bmenu-sort-by-Info-position)
+(define-key bookmark-bmenu-mode-map "sk"                   'bmkp-bmenu-sort-by-bookmark-type)
+(define-key bookmark-bmenu-mode-map "sn"                   'bmkp-bmenu-sort-by-bookmark-name)
+(define-key bookmark-bmenu-mode-map "sr"                   'bmkp-reverse-sort-order)
+(define-key bookmark-bmenu-mode-map "s\C-r"                'bmkp-reverse-multi-sort-order)
+(define-key bookmark-bmenu-mode-map "ss"                   'bmkp-bmenu-change-sort-order-repeat)
+(define-key bookmark-bmenu-mode-map "st"                   'bmkp-bmenu-sort-tagged-before-untagged)
+(define-key bookmark-bmenu-mode-map "su"                   'bmkp-bmenu-sort-by-url)
+(define-key bookmark-bmenu-mode-map "sv"                   'bmkp-bmenu-sort-by-bookmark-visit-frequency)
+
+;; Not done yet.
+;; ;; (define-key bookmark-bmenu-mode-map "sw"                    nil) ; For Emacs20
+;; ;; (define-key bookmark-bmenu-mode-map "swe"                   'bmkp-bmenu-sort-by-eww-url)
+;; ;; (define-key bookmark-bmenu-mode-map "sw3"                   'bmkp-bmenu-sort-by-w3m-url)
+
+(when (> emacs-major-version 22)        ; Emacs 23+
+ (define-key bookmark-bmenu-mode-map (kbd "M-s a C-s")     'bmkp-bmenu-isearch-marked-bookmarks)
+ (define-key bookmark-bmenu-mode-map (kbd "M-s a M-C-s")   'bmkp-bmenu-isearch-marked-bookmarks-regexp))
+(define-key bookmark-bmenu-mode-map (kbd "M-s a M-s")      'bmkp-bmenu-search-marked-bookmarks-regexp)
+(define-key bookmark-bmenu-mode-map "T"                    nil) ; For Emacs20
+(define-key bookmark-bmenu-mode-map "T>+"                  'bmkp-bmenu-add-tags-to-marked)
+(define-key bookmark-bmenu-mode-map "T>-"                  'bmkp-bmenu-remove-tags-from-marked)
+(define-key bookmark-bmenu-mode-map "T>e"                  'bmkp-bmenu-edit-marked)
+(define-key bookmark-bmenu-mode-map "T>l"                  'bmkp-bmenu-list-tags-of-marked)
+(define-key bookmark-bmenu-mode-map "T>p"                  'bmkp-bmenu-paste-add-tags-to-marked)
+(define-key bookmark-bmenu-mode-map "T>q"                  'bmkp-bmenu-paste-replace-tags-for-marked)
+(define-key bookmark-bmenu-mode-map "T>v"                  'bmkp-bmenu-set-tag-value-for-marked)
+(define-key bookmark-bmenu-mode-map "T>\C-y"               'bmkp-bmenu-paste-add-tags-to-marked)
+(define-key bookmark-bmenu-mode-map "T0"                   'bmkp-remove-all-tags)
+(define-key bookmark-bmenu-mode-map "T+"                   'bmkp-add-tags)
+(define-key bookmark-bmenu-mode-map "T-"                   'bmkp-remove-tags)
+(define-key bookmark-bmenu-mode-map "Tc"                   'bmkp-bmenu-copy-tags)
+(define-key bookmark-bmenu-mode-map "Td"                   'bmkp-remove-tags-from-all)
+(define-key bookmark-bmenu-mode-map "Te"                   'bmkp-bmenu-edit-tags)
+(define-key bookmark-bmenu-mode-map "Tl"                   'bmkp-list-all-tags)
+(define-key bookmark-bmenu-mode-map "Tm*"                  'bmkp-bmenu-mark-bookmarks-tagged-all)
+(define-key bookmark-bmenu-mode-map "Tm%"                  'bmkp-bmenu-mark-bookmarks-tagged-regexp)
+(define-key bookmark-bmenu-mode-map "Tm+"                  'bmkp-bmenu-mark-bookmarks-tagged-some)
+(define-key bookmark-bmenu-mode-map "Tm~*"                 'bmkp-bmenu-mark-bookmarks-tagged-not-all)
+(define-key bookmark-bmenu-mode-map "Tm~+"                 'bmkp-bmenu-mark-bookmarks-tagged-none)
+(define-key bookmark-bmenu-mode-map "Tp"                   'bmkp-bmenu-paste-add-tags)
+(define-key bookmark-bmenu-mode-map "Tq"                   'bmkp-bmenu-paste-replace-tags)
+(define-key bookmark-bmenu-mode-map "Tr"                   'bmkp-rename-tag)
+(define-key bookmark-bmenu-mode-map "Ts"                   'bmkp-define-tags-sort-command)
+(define-key bookmark-bmenu-mode-map "TS"                   'bmkp-bmenu-show-only-tagged-bookmarks)
+(define-key bookmark-bmenu-mode-map "TU"                   'bmkp-bmenu-show-only-untagged-bookmarks)
+(define-key bookmark-bmenu-mode-map "Tu*"                  'bmkp-bmenu-unmark-bookmarks-tagged-all)
+(define-key bookmark-bmenu-mode-map "Tu%"                  'bmkp-bmenu-unmark-bookmarks-tagged-regexp)
+(define-key bookmark-bmenu-mode-map "Tu+"                  'bmkp-bmenu-unmark-bookmarks-tagged-some)
+(define-key bookmark-bmenu-mode-map "Tu~*"                 'bmkp-bmenu-unmark-bookmarks-tagged-not-all)
+(define-key bookmark-bmenu-mode-map "Tu~+"                 'bmkp-bmenu-unmark-bookmarks-tagged-none)
+(define-key bookmark-bmenu-mode-map "Tv"                   'bmkp-bmenu-set-tag-value)
+(define-key bookmark-bmenu-mode-map "T\M-w"                'bmkp-bmenu-copy-tags)
+(define-key bookmark-bmenu-mode-map "T\C-y"                'bmkp-bmenu-paste-add-tags)
+(define-key bookmark-bmenu-mode-map "\M-t"                 'bookmark-bmenu-toggle-filenames) ; `t' in Emacs
+(define-key bookmark-bmenu-mode-map "t"                    'bmkp-bmenu-toggle-marks)
+(define-key bookmark-bmenu-mode-map "U"                    'bmkp-bmenu-unmark-all)
+(define-key bookmark-bmenu-mode-map "\M-u"                 nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "\M-u\M-m"             'bmkp-bmenu-mark-url-bookmarks)
+(define-key bookmark-bmenu-mode-map "\M-u\M-s"             'bmkp-bmenu-show-only-url-bookmarks)
+(define-key bookmark-bmenu-mode-map "v"                    'bmkp-bmenu-w32-jump-to-marked)
+(define-key bookmark-bmenu-mode-map "V"                    nil) ; For Emacs20
+(define-key bookmark-bmenu-mode-map "VM"                   'bmkp-bmenu-mark-variable-list-bookmarks)
+(define-key bookmark-bmenu-mode-map "VS"                   'bmkp-bmenu-show-only-variable-list-bookmarks)
+(define-key bookmark-bmenu-mode-map "\M-o"                 'bmkp-bmenu-w32-jump-to-marked)
+(define-key bookmark-bmenu-mode-map "W"                    nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "W3"                   nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "W3M"                  'bmkp-bmenu-mark-w3m-bookmarks)
+(define-key bookmark-bmenu-mode-map "W3S"                  'bmkp-bmenu-show-only-w3m-bookmarks)
+
+(when (fboundp 'bmkp-bmenu-mark-eww-bookmarks) ; Emacs 25+
+  (define-key bookmark-bmenu-mode-map "WEM"                'bmkp-bmenu-mark-eww-bookmarks)
+  (define-key bookmark-bmenu-mode-map "WES"                'bmkp-bmenu-show-only-eww-bookmarks)
+  )
+(define-key bookmark-bmenu-mode-map "w"                    nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "wM"                   'bmkp-bmenu-mark-snippet-bookmarks)
+(define-key bookmark-bmenu-mode-map "wS"                   'bmkp-bmenu-show-only-snippet-bookmarks)
+(define-key bookmark-bmenu-mode-map "X"                    nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "XM"                   'bmkp-bmenu-mark-temporary-bookmarks)
+(define-key bookmark-bmenu-mode-map "XS"                   'bmkp-bmenu-show-only-temporary-bookmarks)
+(define-key bookmark-bmenu-mode-map "\M-X"                 'bmkp-bmenu-toggle-marked-temporary/savable)
+(define-key bookmark-bmenu-mode-map "\C-\M-X"              'bmkp-bmenu-toggle-temporary)
+(define-key bookmark-bmenu-mode-map "Y"                    nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "YM"                   'bmkp-bmenu-mark-bookmark-file-bookmarks)
+(define-key bookmark-bmenu-mode-map "YS"                   'bmkp-bmenu-show-only-bookmark-file-bookmarks)
+(define-key bookmark-bmenu-mode-map "Y>"                   nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "Y>+"                  'bmkp-bmenu-copy-marked-to-bookmark-file)
+(define-key bookmark-bmenu-mode-map "Y>-"                  'bmkp-bmenu-move-marked-to-bookmark-file)
+(define-key bookmark-bmenu-mode-map "Y>0"                  'bmkp-bmenu-create-bookmark-file-from-marked)
+(define-key bookmark-bmenu-mode-map "Z"                    nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "ZM"                   'bmkp-bmenu-mark-bookmark-list-bookmarks)
+(define-key bookmark-bmenu-mode-map "ZS"                   'bmkp-bmenu-show-only-bookmark-list-bookmarks)
+
+
+;;; `Bookmark+' menu-bar menu in `*Bookmark List*'
+
+(defvar bmkp-bmenu-menubar-menu (make-sparse-keymap "Bookmark+") "`Boomark+' menu-bar menu.")
+(define-key bookmark-bmenu-mode-map [menu-bar bmkp]
+  (cons "Bookmark+" bmkp-bmenu-menubar-menu))
+
+;; Top level
+(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-quit]
+  '(menu-item "Quit" bmkp-bmenu-quit
+    :help "Quit the bookmark list, saving its state and the current set of bookmarks"))
+(define-key bmkp-bmenu-menubar-menu [bmkp-list-defuns-in-commands-file]
+  '(menu-item "List User-Defined Bookmark Commands" bmkp-list-defuns-in-commands-file
+    :help "List the functions defined in `bmkp-bmenu-commands-file'"))
+(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-describe-marked]
+  '(menu-item "Describe Marked Bookmarks" bmkp-bmenu-describe-marked
+    :help "Describe the marked bookmarks.  With `C-u' show internal format."))
+(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-describe-this-bookmark]
+  '(menu-item "Describe This Bookmark" bmkp-bmenu-describe-this-bookmark
+    :help "Describe this line's bookmark.  With `C-u' show internal format."))
+(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-mode-status-help]
+  '(menu-item "Current Status, Mode Help" bmkp-bmenu-mode-status-help :keys "?"
+    :help "Describe `*Bookmark List*' and show its current status"))
+
+(define-key bmkp-bmenu-menubar-menu [top-sep7] '("--")) ; ------------
+(define-key bmkp-bmenu-menubar-menu [bmkp-revert-bookmark-file]
+  '(menu-item "Revert to Saved..." bmkp-revert-bookmark-file
+    :help "Revert to bookmarks in current bookmark file, as last saved" :keys "C-u g"))
+(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-refresh-menu-list]
+  '(menu-item "Refresh to Current" bmkp-bmenu-refresh-menu-list
+    :help "Update display to reflect current bookmark list (`C-u': revert from file)"))
+
+(define-key bmkp-bmenu-menubar-menu [top-sep6] '("--")) ; ------------
+(define-key bmkp-bmenu-menubar-menu [bmkp-save-menu-list-state]
+  '(menu-item "Save Display State..." bmkp-save-menu-list-state
+    :help "Save the current bookmark-list display state to `bmkp-bmenu-state-file'"
+    :enable (and (not bmkp-bmenu-first-time-p)  bmkp-bmenu-state-file)))
+(define-key bmkp-bmenu-menubar-menu [bookmark-write]
+  '(menu-item "Save As..." bookmark-write
+    :help "Write the current set of bookmarks to a file whose name you enter"))
+(define-key bmkp-bmenu-menubar-menu [bookmark-bmenu-save]
+  '(menu-item "Save" bookmark-bmenu-save
+    :help "Save the current set of bookmarks to the current bookmark file"
+    :enable (> bookmark-alist-modification-count 0)))
+
+(define-key bmkp-bmenu-menubar-menu [top-sep5] '("--")) ; ----------
+(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-relocate-marked]
+  '(menu-item "Relocate Marked..." bmkp-bmenu-relocate-marked
+    :help "Relocate the marked bookmarks to a directory"))
+
+(define-key bmkp-bmenu-menubar-menu [top-sep4] '("--")) ; ----------
+(define-key bmkp-bmenu-menubar-menu [bmkp-make-function-bookmark]
+  '(menu-item "New Function Bookmark..." bmkp-make-function-bookmark
+    :help "Create a bookmark that will invoke FUNCTION when \"jumped\" to"))
+(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-make-sequence-from-marked]
+  '(menu-item "New Sequence Bookmark from Marked..." bmkp-bmenu-make-sequence-from-marked
+    :help "Create or update a sequence bookmark from the visible marked bookmarks"))
+(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-clone-bookmark]
+  '(menu-item "Clone (Duplicate) This Bookmark" bmkp-bmenu-clone-bookmark
+    :help "Clone this bookmark.  (`\\[bmkp-bmenu-edit-bookmark-record]' to edit.)"))
+
+(define-key bmkp-bmenu-menubar-menu [top-sep3] '("--")) ; ----------
+(define-key bmkp-bmenu-menubar-menu [bmkp-choose-navlist-from-bookmark-list]
+  '(menu-item "Set Navlist from Bookmark-List Bookmark..." bmkp-choose-navlist-from-bookmark-list
+    :help "Set the navigation list from a bookmark-list bookmark"))
+(define-key bmkp-bmenu-menubar-menu [bmkp-choose-navlist-of-type]
+  '(menu-item "Set Navlist to Bookmarks of Type..." bmkp-choose-navlist-of-type
+    :help "Set the navigation list to the bookmarks of a certain type"))
+
+(define-key bmkp-bmenu-menubar-menu [top-sep2] '("--")) ; ----------
+
+(defvar bmkp-bmenu-define-command-menu (make-sparse-keymap "Define Command")
+    "`Define Command' submenu for menu-bar `Bookmark+' menu.")
+(define-key bmkp-bmenu-menubar-menu [define-command]
+  (cons "Define Command" bmkp-bmenu-define-command-menu))
+
+(defvar bmkp-bmenu-bookmark-file-menu (make-sparse-keymap "Bookmark File")
+    "`Bookmark File' submenu for menu-bar `Bookmark+' menu.")
+(define-key bmkp-bmenu-menubar-menu [bookmark-file] (cons "Bookmark File" bmkp-bmenu-bookmark-file-menu))
+
+(when (or (featurep 'bookmark+-lit)
+          (and (fboundp 'diredp-highlight-autofiles-mode)  (featurep 'highlight)))
+  (defvar bmkp-bmenu-highlight-menu (make-sparse-keymap "Highlight")
+    "`Highlight' submenu for menu-bar `Bookmark+' menu.")
+  (define-key bmkp-bmenu-menubar-menu [highlight] (cons "Highlight" bmkp-bmenu-highlight-menu)))
+
+(defvar bmkp-bmenu-tags-menu (make-sparse-keymap "Tags")
+    "`Tags' submenu for menu-bar `Bookmark+' menu.")
+(define-key bmkp-bmenu-menubar-menu [tags] (cons "Tags" bmkp-bmenu-tags-menu))
+
+(defvar bmkp-bmenu-search-menu (make-sparse-keymap "Search")
+    "`Search' submenu for menu-bar `Bookmark+' menu.")
+(define-key bmkp-bmenu-menubar-menu [search] (cons "Search" bmkp-bmenu-search-menu))
+
+(defvar bmkp-bmenu-sort-menu (make-sparse-keymap "Sort")
+    "`Sort' submenu for menu-bar `Bookmark+' menu.")
+(define-key bmkp-bmenu-menubar-menu [sort] (cons "Sort" bmkp-bmenu-sort-menu))
+
+(defvar bmkp-bmenu-edit-menu (make-sparse-keymap "Edit")
+    "`Edit' submenu for menu-bar `Bookmark+' menu.")
+(define-key bmkp-bmenu-menubar-menu [edit] (cons "Edit" bmkp-bmenu-edit-menu))
+
+(defvar bmkp-bmenu-show-menu (make-sparse-keymap "Show")
+    "`Show' submenu for menu-bar `Bookmark+' menu.")
+(define-key bmkp-bmenu-menubar-menu [show] (cons "Show" bmkp-bmenu-show-menu))
+
+(defvar bmkp-bmenu-omit-menu (make-sparse-keymap "Omit")
+  "`Omit' submenu for menu-bar `Bookmark+' menu.")
+(define-key bmkp-bmenu-menubar-menu [omitting] (cons "Omit" bmkp-bmenu-omit-menu))
+
+(defvar bmkp-bmenu-mark-menu (make-sparse-keymap "Mark")
+    "`Mark' submenu for menu-bar `Bookmark+' menu.")
+(define-key bmkp-bmenu-menubar-menu [marking] (cons "Mark" bmkp-bmenu-mark-menu))
+
+(defvar bmkp-bmenu-delete-menu (make-sparse-keymap "Delete")
+    "`Delete' submenu for menu-bar `Bookmark+' menu.")
+(define-key bmkp-bmenu-menubar-menu [delete] (cons "Delete" bmkp-bmenu-delete-menu))
+
+(defvar bmkp-bmenu-toggle-menu (make-sparse-keymap "Toggle")
+    "`Toggle' submenu for menu-bar menus `Bookmark+' and `Bookmarks'.")
+(define-key bmkp-bmenu-menubar-menu [toggle] (cons "Toggle" bmkp-bmenu-toggle-menu))
+
+
+;;; `Define Command' submenu -----------------------------------------
+(define-key bmkp-bmenu-define-command-menu [bmkp-bmenu-define-full-snapshot-command]
+  '(menu-item "To Restore Full Bookmark-List State..." bmkp-bmenu-define-full-snapshot-command
+    :help "Define a command to restore the current bookmark-list state"))
+(define-key bmkp-bmenu-define-command-menu [bmkp-bmenu-define-command]
+  '(menu-item "To Restore Current Order and Filter..." bmkp-bmenu-define-command
+    :help "Define a command to use the current sort order, filter, and omit list"))
+(define-key bmkp-bmenu-define-command-menu [bmkp-define-tags-sort-command]
+  '(menu-item "To Sort by Specific Tags..." bmkp-define-tags-sort-command
+    :help "Define a command to sort bookmarks in the bookmark list by certain tags"))
+(define-key bmkp-bmenu-define-command-menu [bmkp-bmenu-define-jump-marked-command]
+  '(menu-item "To Jump to a Bookmark Now Marked..." bmkp-bmenu-define-jump-marked-command
+    :help "Define a command to jump to one of the bookmarks that is now marked"
+    :enable bmkp-bmenu-marked-bookmarks))
+
+
+;;; `Bookmark File' submenu ------------------------------------------
+(define-key bmkp-bmenu-bookmark-file-menu [bmkp-bmenu-set-bookmark-file-bookmark-from-marked]
+  '(menu-item "Set Bookmark-File Bookmark from Marked..."
+    bmkp-bmenu-set-bookmark-file-bookmark-from-marked
+    :help "Create a bookmark file and a bookmark for it, from the marked bookmarks"
+    :keys "C-u Y > 0"))
+(define-key bmkp-bmenu-bookmark-file-menu [bmkp-bmenu-create-bookmark-file-from-marked]
+  '(menu-item "Copy Marked to New Bookmark File..." bmkp-bmenu-create-bookmark-file-from-marked
+    :help "Create a bookmark file by copying the marked bookmarks (or current bookmark)"))
+(define-key bmkp-bmenu-bookmark-file-menu [bmkp-bmenu-copy-marked-to-bookmark-file]
+  '(menu-item "Copy Marked to Bookmark File..." bmkp-bmenu-copy-marked-to-bookmark-file
+    :help "Copy the marked bookmarks (or current bookmark) to a bookmark file"))
+(define-key bmkp-bmenu-bookmark-file-menu [bmkp-bmenu-move-marked-to-bookmark-file]
+  '(menu-item "Move Marked to Bookmark File..." bmkp-bmenu-move-marked-to-bookmark-file
+    :help "Move the marked bookmarks (or current bookmark) to a different bookmark file"))
+
+(define-key bmkp-bmenu-bookmark-file-menu [sep] '("--")) ; ------------
+(define-key bmkp-bmenu-bookmark-file-menu [bmkp-bmenu-load-marked-bookmark-file-bookmarks]
+  '(menu-item "Load Marked Bookmark-File Bookmarks..." bmkp-bmenu-load-marked-bookmark-file-bookmarks
+    :help "Load the marked bookmark-file bookmarks, in order"))
+(define-key bmkp-bmenu-bookmark-file-menu [bmkp-bmenu-load-marking-unmark-first]
+  '(menu-item "Load Bookmarks, Mark Only Those Loaded...." bmkp-bmenu-load-marking-unmark-first
+    :help "`bookmark-load', marking those loaded, unmarking others"))
+(define-key bmkp-bmenu-bookmark-file-menu [bmkp-bmenu-load-marking]
+  '(menu-item "Load Bookmarks, Mark Those Loaded...." bmkp-bmenu-load-marking
+    :help "`bookmark-load', marking bookmarks that are loaded"))
+(define-key bmkp-bmenu-bookmark-file-menu [bf-sep2] '("--")) ; ------------
+;;; (define-key bmkp-bmenu-bookmark-file-menu [bmkp-save-bookmarks-this-file/buffer]
+;;;   '(menu-item "Save Bookmarks Here to File (No Switch)..." bmkp-save-bookmarks-this-file/buffer
+;;;     :help "Save bookmarks defined for the current file or buffer to file"))
+;;; (define-key bmkp-bmenu-bookmark-file-menu [bmkp-switch-to-bookmark-file-this-file/buffer]
+;;;   '(menu-item "Switch to Bookmarks Here..." bmkp-switch-to-bookmark-file-this-file/buffer
+;;;     :help "Switch to a bookmark file with only bookmarks for this file or buffer"))
+(define-key bmkp-bmenu-bookmark-file-menu [bmkp-switch-to-last-bookmark-file]
+  '(menu-item "Switch to Last Bookmark File" bmkp-switch-to-last-bookmark-file
+    :help "Switch back to last set of bookmarks used, *replacing* current set" :keys "C-u L"))
+(define-key bmkp-bmenu-bookmark-file-menu [bmkp-switch-bookmark-file-create]
+  '(menu-item "Switch to Bookmarks..." bmkp-switch-bookmark-file-create
+    :help "Switch to another bookmark file, *replacing* the current set of bookmarks"))
+(define-key bmkp-bmenu-bookmark-file-menu [bookmark-bmenu-load]
+  '(menu-item "Load (Add) Bookmarks..." bookmark-bmenu-load
+    :help "Load additional bookmarks from a bookmark file"))
+(define-key bmkp-bmenu-bookmark-file-menu [bf-sep1] '("--")) ; ------------
+(define-key bmkp-bmenu-bookmark-file-menu [bmkp-empty-file]
+  '(menu-item "Empty Bookmark File..." bmkp-empty-file
+    :help "Empty an existing bookmark file or create a new, empty bookmark file"))
+(define-key bmkp-bmenu-bookmark-file-menu [bmkp-revert-bookmark-file]
+  '(menu-item "Revert to Saved Bookmarks..." bmkp-revert-bookmark-file
+    :help "Revert to bookmarks in current bookmark file, as last saved" :keys "C-u g"))
+
+
+;;; `Toggle' submenu -------------------------------------------------
+
+(define-key bmkp-bmenu-toggle-menu [diredp-highlight-autofiles-mode]
+  (bmkp-menu-bar-make-toggle diredp-highlight-autofiles-mode
+                             diredp-highlight-autofiles-mode
+                             "Autofile Highlighting in Dired"
+                             "Whether to highlight autofile bookmarks in Dired us biw %s"
+                             "Toggle the value of option `diredp-highlight-autofiles-mode'"
+                             nil
+                             :visible (and (fboundp 'diredp-highlight-autofiles-mode)
+                                           (featurep 'highlight))))
+(define-key bmkp-bmenu-toggle-menu [bmkp-toggle-guess-default-file-handler]
+  (bmkp-menu-bar-make-toggle bmkp-toggle-guess-default-file-handler
+                             bmkp-guess-default-handler-for-file-flag
+                             "Guessing Default File Handler"
+                             "Guessing the default handler when creating a file bookmark is now %s"
+                             "Toggle the value of option `bmkp-guess-default-handler-for-file-flag'"))
+(define-key bmkp-bmenu-toggle-menu [bmkp-toggle-auto-light-when-jump-menu]
+  (bmkp-menu-bar-make-toggle bmkp-toggle-auto-light-when-jump-menu bmkp-auto-light-when-jump
+                             "Automatic Highlighting When Jumping"
+                             "Bookmark highlighting when you jump to a bookmark is now %s"
+                             "Toggle the value of option `bmkp-auto-light-when-jump'"
+                             (bmkp-toggle-auto-light-when-jump)
+                             :visible (featurep 'bookmark+-lit)))
+(define-key bmkp-bmenu-toggle-menu [bmkp-toggle-auto-light-when-set-menu]
+  (bmkp-menu-bar-make-toggle bmkp-toggle-auto-light-when-set-menu bmkp-auto-light-when-set
+                             "Automatic Highlighting When Setting"
+                             "Bookmark highlighting when you set a bookmark is now %s"
+                             "Toggle the value of option `bmkp-auto-light-when-set'"
+                             (bmkp-toggle-auto-light-when-set)
+                             :visible (featurep 'bookmark+-lit)))
+(define-key bmkp-bmenu-toggle-menu [bmkp-toggle-prompt-for-tags]
+  (bmkp-menu-bar-make-toggle bmkp-toggle-prompt-for-tags bmkp-prompt-for-tags-flag
+                             "Prompting for Tags When Setting"
+                             "Prompting for tags when you set a bookmark is now %s"
+                             "Toggle the value of option `bmkp-prompt-for-tags-flag'"))
+(define-key bmkp-bmenu-toggle-menu [bmkp-toggle-propertize-bookmark-names]
+  (bmkp-menu-bar-make-toggle bmkp-toggle-propertize-bookmark-names bmkp-propertize-bookmark-names-flag
+                             "Allowing Identical Bookmark Names"
+                             "Allowing multiple bookmarks with the same name is now %s"
+                             "Toggle the value of option `bmkp-propertize-bookmark-names-flag'"
+                             nil
+                             :visible (> emacs-major-version 20)))
+
+(define-key bmkp-bmenu-toggle-menu [sep4] '("--")) ; ------------ Jumping-behavior stuff
+(define-key bmkp-bmenu-toggle-menu [bmkp-toggle-w3m-allow-multiple-buffers]
+  (bmkp-menu-bar-make-toggle bmkp-toggle-w3m-allow-multiple-buffers bmkp-w3m-allow-multiple-buffers-flag
+                             "Using Multiple Buffers for W3M"
+                             "Using a new buffer when jumping to a W3M bookmark is now %s"
+                             "Toggle the value of option `bmkp-w3m-allow-multiple-buffers-flag'"))
+(when (boundp 'bmkp-eww-allow-multiple-buffers-flag) ; Emacs 25+
+  (define-key bmkp-bmenu-toggle-menu [bmkp-toggle-eww-allow-multiple-buffers]
+    (bmkp-menu-bar-make-toggle bmkp-toggle-eww-allow-multiple-buffers bmkp-eww-allow-multiple-buffers-flag
+                               "Using Multiple Buffers for EWW"
+                               "Using a new buffer when jumping to an EWW bookmark is now %s"
+                               "Toggle the value of option `bmkp-eww-allow-multiple-buffers-flag'"))
+  )
+(define-key bmkp-bmenu-toggle-menu [bmkp-toggle-showing-region-end]
+  (bmkp-menu-bar-make-toggle bmkp-toggle-showing-region-end bmkp-show-end-of-region-flag
+                             "Showing Region End"
+                             "Showing the end of the region when activating is now %s"
+                             "Toggle the value of option `bmkp-show-end-of-region-flag'"))
+(define-key bmkp-bmenu-toggle-menu [bmkp-toggle-pop-to]
+  (bmkp-menu-bar-make-toggle bmkp-toggle-pop-to bmkp-other-window-pop-to-flag
+                             "Using `pop-to-buffer'"
+                             "Using `pop-to-buffer' instead of `switch-to-buffer-other-window' is now %s"
+                             "Toggle the value of option `bmkp-other-window-pop-to-flag'"))
+(define-key bmkp-bmenu-toggle-menu [bmkp-toggle-auto-light-when-jump-menu]
+  (bmkp-menu-bar-make-toggle bmkp-toggle-auto-light-when-jump-menu bmkp-auto-light-when-jump
+                             "Automatic Highlighting When Jumping"
+                             "Bookmark highlighting when you jump to a bookmark is now %s"
+                             "Toggle the value of option `bmkp-auto-light-when-jump'"
+                             (progn (bmkp-toggle-auto-light-when-jump) bmkp-auto-light-when-jump)
+                             :visible (featurep 'bookmark+-lit)))
+(when (> emacs-major-version 21)
+  (define-key bmkp-bmenu-toggle-menu [bmkp-toggle-crosshairs]
+    (bmkp-menu-bar-make-toggle bmkp-toggle-crosshairs bmkp-crosshairs-flag
+                               "Crosshairs Highlighting"
+                               "Highlighting bookmark location with crosshairs is now %s"
+                               "Toggle the value of option `bmkp-crosshairs-flag'"
+                               nil
+                               :visible (featurep 'crosshairs))))
+
+(define-key bmkp-bmenu-toggle-menu [sep3] '("--")) ; ------------ Temporary bookmark stuff
+(define-key bmkp-bmenu-toggle-menu [bmkp-bmenu-toggle-marked-temporary/savable]
+  '(menu-item "Temporary/Savable (`X') for Marked" bmkp-bmenu-toggle-marked-temporary/savable
+    :help "Toggle the temporary (`X') vs. savable status of the marked bookmarks"))
+(define-key bmkp-bmenu-toggle-menu [bmkp-temporary-bookmarking-mode]
+  (bmkp-menu-bar-make-toggle bmkp-temporary-bookmarking-mode bmkp-temporary-bookmarking-mode
+                             "Temporary Bookmarking"
+                             "Temporary bookmarking mode is now %s"
+                             "Toggle automatically saving bookmark changes"))
+(define-key bmkp-bmenu-toggle-menu [bmkp-toggle-autotemp-on-set]
+  (bmkp-menu-bar-make-toggle bmkp-toggle-autotemp-on-set bmkp-autotemp-all-when-set-p
+                             "Making Bookmarks Temporary When Set"
+                             "Automatically making bookmarks temporary when you set them is now %s"
+                             "Toggle automatically making a bookmark temporary when you set it"))
+
+(define-key bmkp-bmenu-toggle-menu [sep2] '("--")) ; ------------ List display stuff
+(define-key bmkp-bmenu-toggle-menu [bmkp-toggle-bookmark-set-refreshes]
+  '(menu-item "Autorefresh for `bmkp-latest-bookmark-alist'" bmkp-toggle-bookmark-set-refreshes
+    :help "Toggle whether `bookmark-set' refreshes `bmkp-latest-bookmark-alist'"))
+(define-key bmkp-bmenu-toggle-menu [bmkp-toggle-count-multi-mods-as-one]
+  (bmkp-menu-bar-make-toggle bmkp-toggle-count-multi-mods-as-one bmkp-count-multi-mods-as-one-flag
+                             "Counting Multiple Modifications As One"
+                             "Counting multiple modifications as one is now %s"
+                             "Toggle the value of option `bmkp-count-multi-mods-as-one-flag'"))
+(define-key bmkp-bmenu-toggle-menu [bmkp-bmenu-toggle-marks]
+  '(menu-item "Marked/Unmarked" bmkp-bmenu-toggle-marks
+    :help "Unmark all marked bookmarks; mark all unmarked bookmarks"))
+(define-key bmkp-bmenu-toggle-menu [bmkp-reverse-sort-order]
+  '(menu-item "Sort Direction" bmkp-reverse-sort-order
+    :help "Toggle the current bookmark sort direction"
+    :enable (bmkp-current-sort-order)))
+(define-key bmkp-bmenu-toggle-menu [bmkp-bmenu-toggle-show-only-unmarked]
+  '(menu-item "Showing Only Unmarked" bmkp-bmenu-toggle-show-only-unmarked
+    :help "Alternately show unmarked or all bookmarks"))
+(define-key bmkp-bmenu-toggle-menu [bmkp-bmenu-toggle-show-only-marked]
+  '(menu-item "Showing Only Marked" bmkp-bmenu-toggle-show-only-marked
+    :help "Alternately show unmarked or all bookmarks"))
+(define-key bmkp-bmenu-toggle-menu [bmkp-bmenu-toggle-filenames]
+  (bmkp-menu-bar-make-toggle bmkp-bmenu-toggle-filenames bookmark-bmenu-toggle-filenames
+                             "Showing File Names"
+                             "Showing file names is now %s"
+                             "Toggle the value of option `bookmark-bmenu-toggle-filenames'"
+                             (progn
+                               (custom-load-symbol 'bookmark-bmenu-toggle-filenames)
+                               (let ((set  (or (get 'bookmark-bmenu-toggle-filenames 'custom-set)
+                                               'set-default))
+                                     (get  (or (get 'bookmark-bmenu-toggle-filenames 'custom-get)
+                                               'default-value)))
+                                 (funcall set 'bookmark-bmenu-toggle-filenames
+                                          (not (funcall get 'bookmark-bmenu-toggle-filenames))))
+                               (if bookmark-bmenu-toggle-filenames
+                                   (bookmark-bmenu-show-filenames)
+                                 (bookmark-bmenu-hide-filenames))
+                               bookmark-bmenu-toggle-filenames)
+                             :keys "M-t"))
+(define-key bmkp-bmenu-toggle-menu [bmkp-toggle-saving-menu-list-state]
+  (bmkp-menu-bar-make-toggle bmkp-toggle-saving-menu-list-state bmkp-bmenu-state-file
+                             "Saving Display State"
+                             "Ability to save bookmark list state, and autosaving, are now %s"
+                             "Toggle the value of option `bmkp-bmenu-state-file'"))
+
+(define-key bmkp-bmenu-toggle-menu [sep1] '("--")) ; ------------ Automatic stuff
+(define-key bmkp-bmenu-toggle-menu [bmkp-automatic-bookmark-mode]
+  '(menu-item "Automatically Creating Bookmarks" bmkp-automatic-bookmark-mode
+    :help "Toggle the periodic automatic creation of bookmarks"))
+(define-key bmkp-bmenu-toggle-menu [bmkp-toggle-save-desktop-before-switching]
+  (bmkp-menu-bar-make-toggle bmkp-toggle-save-desktop-before-switching bmkp-desktop-jump-save-before-flag
+                             "Autosaving the Desktop Before Switching"
+                             "Autosaving the desktop before jumping to a desktop bookmark is now %s"
+                             "Toggle the value of option `bmkp-desktop-jump-save-before-flag'"))
+(define-key bmkp-bmenu-toggle-menu [bmkp-toggle-saving-relocated]
+  (bmkp-menu-bar-make-toggle bmkp-toggle-saving-relocated bmkp-save-new-location-flag
+                             "Autosaving Relocated Bookmarks"
+                             "Automatically saving relocated bookmarks is now %s"
+                             "Toggle the value of option `bmkp-save-new-location-flag'"))
+(define-key bmkp-bmenu-toggle-menu [bmkp-toggle-saving-bookmark-file]
+  (bmkp-menu-bar-make-toggle bmkp-toggle-saving-bookmark-file bookmark-save-flag
+                             "Autosaving Bookmark File"
+                             "Automatically saving the bookmark file (`bookmark-save-flag') is now %s"
+                             "Toggle the value of option `bookmark-save-flag'"))
+
+
+;;; `Highlight' submenu ----------------------------------------------
+(when (boundp 'bmkp-bmenu-highlight-menu)
+  (define-key bmkp-bmenu-highlight-menu [diredp-highlight-autofiles-mode]
+    (bmkp-menu-bar-make-toggle diredp-highlight-autofiles-mode
+                               diredp-highlight-autofiles-mode
+                               "Toggle Autofile Highlighting in Dired"
+                               "Whether to highlight autofile bookmarks in Dired us biw %s"
+                               "Toggle `diredp-highlight-autofiles-mode'"
+                               nil
+                               :visible (and (fboundp 'diredp-highlight-autofiles-mode)
+                                             (featurep 'highlight))))
+  (when (featurep 'bookmark+-lit)
+    (define-key bmkp-bmenu-highlight-menu [bmkp-bmenu-show-only-lighted-bookmarks]
+      '(menu-item "Show Only Highlighted" bmkp-bmenu-show-only-lighted-bookmarks
+        :help "Display (only) highlighted bookmarks"))
+    (define-key bmkp-bmenu-highlight-menu [bmkp-bmenu-set-lighting-for-marked]
+      '(menu-item "Set Highlighting for Marked" bmkp-bmenu-set-lighting-for-marked
+        :help "Set specific highlighting for the marked bookmarks"
+        :enable bmkp-bmenu-marked-bookmarks))
+    (define-key bmkp-bmenu-highlight-menu [bmkp-bmenu-unlight-marked]
+      '(menu-item "Unhighlight Marked" bmkp-bmenu-unlight-marked
+        :help "Unhighlight the marked bookmarks"
+        :enable bmkp-bmenu-marked-bookmarks))
+    (define-key bmkp-bmenu-highlight-menu [bmkp-bmenu-light-marked]
+      '(menu-item "Highlight Marked" bmkp-bmenu-light-marked
+        :help "Highlight the marked bookmarks"
+        :enable bmkp-bmenu-marked-bookmarks))))
+
+
+;;; `Tags' submenu ---------------------------------------------------
+(define-key bmkp-bmenu-tags-menu [bmkp-list-all-tags]
+  '(menu-item "List All Tags" bmkp-list-all-tags
+    :help "List all tags used for any bookmarks (`C-u': show full, internal form)"))
+(define-key bmkp-bmenu-tags-menu [bmkp-bmenu-list-tags-of-marked]
+  '(menu-item "List Tags of Marked" bmkp-bmenu-list-tags-of-marked
+    :help "List all tags used in the marked bookmarks (`C-u': show full, internal form)"))
+(define-key bmkp-bmenu-tags-menu [bmkp-purge-notags-autofiles]
+  '(menu-item "Purge Autofiles with No Tags..." bmkp-purge-notags-autofiles
+    :help "Delete all autofile bookmarks that have no tags"))
+(define-key bmkp-bmenu-tags-menu [bmkp-untag-a-file]
+  '(menu-item "Untag a File (Remove Some)..." bmkp-untag-a-file
+    :help "Remove some tags from autofile bookmark for a file"))
+(define-key bmkp-bmenu-tags-menu [bmkp-tag-a-file]
+  '(menu-item "Tag a File (Add Some)..." bmkp-tag-a-file
+    :help "Add some tags to the autofile bookmark for a file"))
+
+(define-key bmkp-bmenu-tags-menu [tags-sep] '("--")) ; ---------------
+(define-key bmkp-bmenu-tags-menu [bmkp-rename-tag]
+  '(menu-item "Rename Tag..." bmkp-rename-tag
+    :help "Rename a tag in all bookmarks, even those not showing"))
+(define-key bmkp-bmenu-tags-menu [bmkp-bmenu-edit-marked]
+  '(menu-item "Edit Tags of Marked (Lisp)" bmkp-bmenu-edit-marked
+    :help "Edit internal records of marked bookmarks (which include their tags)"
+    :keys "T > e"))
+(define-key bmkp-bmenu-tags-menu [bmkp-bmenu-set-tag-value-for-marked]
+  '(menu-item "Set Tag Value for Marked..." bmkp-bmenu-set-tag-value-for-marked
+    :help "Set the value of a tag, for each of the marked bookmarks"))
+(define-key bmkp-bmenu-tags-menu [bmkp-remove-tags-from-all]
+  '(menu-item "Remove Some Tags from All..." bmkp-remove-tags-from-all
+    :help "Remove a set of tags from all bookmarks"))
+(define-key bmkp-bmenu-tags-menu [bmkp-bmenu-remove-tags-from-marked]
+  '(menu-item "Remove Some Tags from Marked..." bmkp-bmenu-remove-tags-from-marked
+    :help "Remove a set of tags from each of the marked bookmarks"))
+(define-key bmkp-bmenu-tags-menu [bmkp-bmenu-add-tags-to-marked]
+  '(menu-item "Add Some Tags to Marked..." bmkp-bmenu-add-tags-to-marked
+    :help "Add a set of tags to each of the marked bookmarks"))
+(define-key bmkp-bmenu-tags-menu [bmkp-bmenu-paste-replace-tags-for-marked]
+  '(menu-item "Paste Tags to Marked (Replace)..." bmkp-bmenu-paste-replace-tags-for-marked
+    :help "Replace tags for the marked bookmarks with set of tags copied previously"))
+(define-key bmkp-bmenu-tags-menu [bmkp-bmenu-paste-add-tags-to-marked]
+  '(menu-item "Paste Tags to Marked (Add)..." bmkp-bmenu-paste-add-tags-to-marked
+    :help "Add tags copied from another bookmark to the marked bookmarks"
+    :enable bmkp-copied-tags))
+(define-key bmkp-bmenu-tags-menu [bmkp-bmenu-copy-tags]
+  '(menu-item "Copy Tags from This Bookmark" bmkp-bmenu-copy-tags
+    :help "Copy tags from this bookmark, so you can paste them to other bookmarks"))
+
+
+;;; `Search' submenu -------------------------------------------------
+(define-key bmkp-bmenu-search-menu [bmkp-bmenu-query-replace-marked-bookmarks-regexp]
+  '(menu-item "Query-Replace Marked..." bmkp-bmenu-query-replace-marked-bookmarks-regexp
+    :help "`query-replace-regexp' over all files whose bookmarks are marked"))
+(when (fboundp 'bmkp-bmenu-isearch-marked-bookmarks)
+  (define-key bmkp-bmenu-search-menu [bmkp-bmenu-isearch-marked-bookmarks-regexp]
+    '(menu-item "Regexp-Isearch Marked..." bmkp-bmenu-isearch-marked-bookmarks-regexp
+      :help "Regexp Isearch the marked bookmark locations, in their current order"))
+  (define-key bmkp-bmenu-search-menu [bmkp-bmenu-isearch-marked-bookmarks]
+    '(menu-item "Isearch Marked..." bmkp-bmenu-isearch-marked-bookmarks
+      :help "Isearch the marked bookmark locations, in their current order")))
+(define-key bmkp-bmenu-search-menu [bmkp-bmenu-search-marked-bookmarks-regexp]
+  '(menu-item "Search Marked..." bmkp-bmenu-search-marked-bookmarks-regexp
+    :help "Regexp-search the files whose bookmarks are marked, in their current order"))
+
+
+;;; `Sort' submenu ---------------------------------------------------
+(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-url]
+  '(menu-item "By URL" bmkp-bmenu-sort-by-url
+    :help "Sort URL bookmarks alphabetically by their URL/filename"))
+(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-Gnus-thread]
+  '(menu-item "By Gnus Thread" bmkp-bmenu-sort-by-Gnus-thread
+    :help "Sort Gnus bookmarks by group, then by article, then by message"))
+(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-Info-node-name]
+  '(menu-item "By Info Node Name" bmkp-bmenu-sort-by-Info-node-name
+    :help "Sort Info bookmarks by manual (file) name, then node name, then position"))
+(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-Info-position]
+  '(menu-item "By Info Book Order" bmkp-bmenu-sort-by-Info-position
+    :help "Sort Info bookmarks by manual (file) name, then position (order in book)"))
+(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-last-local-file-update]
+  '(menu-item "By Last Local File Update" bmkp-bmenu-sort-by-last-local-file-update
+    :help "Sort bookmarks by last local file update time"))
+(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-last-buffer-or-file-access]
+  '(menu-item "By Last Buffer/File Access" bmkp-bmenu-sort-by-last-buffer-or-file-access
+    :help "Sort bookmarks by time of last buffer access or local-file access"))
+(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-local-file-size]
+  '(menu-item "By Local File Size" bmkp-bmenu-sort-by-local-file-size
+    :help "Sort bookmarks by local file size"))
+(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-local-file-type]
+  '(menu-item "By Local File Type" bmkp-bmenu-sort-by-local-file-type
+    :help "Sort bookmarks by local file type: file, symlink, directory"))
+(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-bookmark-type]
+  '(menu-item "By Type" bmkp-bmenu-sort-by-bookmark-type
+    :help "Sort bookmarks by type: Info, URL, Gnus, files, other"))
+(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-file-name]
+  '(menu-item "By File Name" bmkp-bmenu-sort-by-file-name :help "Sort bookmarks by file name"))
+(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-bookmark-name]
+  '(menu-item "By Bookmark Name" bmkp-bmenu-sort-by-bookmark-name
+    :help "Sort bookmarks by bookmark name, respecting `case-fold-search'"))
+(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-creation-time]
+  '(menu-item "By Creation Time" bmkp-bmenu-sort-by-creation-time
+    :help "Sort bookmarks by the time of their creation"))
+(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-last-bookmark-access]
+  '(menu-item "By Last Bookmark Access" bmkp-bmenu-sort-by-last-bookmark-access
+    :help "Sort bookmarks by the time of their last visit as bookmarks"))
+(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-bookmark-visit-frequency]
+  '(menu-item "By Bookmark Use" bmkp-bmenu-sort-by-bookmark-visit-frequency
+    :help "Sort bookmarks by the number of times they were visited as bookmarks"))
+(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-marked-before-unmarked]
+  '(menu-item "Marked Before Unmarked" bmkp-bmenu-sort-marked-before-unmarked
+    :help "Sort bookmarks by putting marked before unmarked"))
+(define-key bmkp-bmenu-sort-menu [bmkp-reverse-sort-order]
+  '(menu-item "Reverse" bmkp-reverse-sort-order :help "Reverse the current bookmark sort order"))
+
+;;; `Edit' submenu ---------------------------------------------------
+(define-key bmkp-bmenu-edit-menu [bmkp-bmenu-edit-marked]
+  '(menu-item "Edit Full Records of Marked (Lisp)" bmkp-bmenu-edit-marked
+    :help "Edit the full internal records of the marked bookmarks" :keys "E"))
+(define-key bmkp-bmenu-edit-menu [bmkp-bmenu-edit-bookmark-record]
+  '(menu-item "Edit Full Record (Lisp)" bmkp-bmenu-edit-bookmark-record
+    :help "Edit full record (Lisp sexp) for this bookmark, in another window"))
+(define-key bmkp-bmenu-edit-menu [bmkp-bmenu-edit-annotations-for-marked]
+  '(menu-item "Edit Annotations of Marked" bmkp-bmenu-edit-annotations-for-marked
+    :help "Edit annotations (created if missing) for the marked bookmarks"))
+(define-key bmkp-bmenu-edit-menu [bookmark-bmenu-edit-annotation]
+  '(menu-item "Edit Annotation" bookmark-bmenu-edit-annotation
+    :help "Edit annotation for this bookmark (create if none), in another window"))
+
+;;; `Show' submenu ---------------------------------------------------
+(define-key bmkp-bmenu-show-menu [bookmark-bmenu-show-all-annotations]
+  '(menu-item "Show All Annotations" bookmark-bmenu-show-all-annotations
+    :help "Show the annotations for all bookmarks (in another window)"))
+(define-key bmkp-bmenu-show-menu [bookmark-bmenu-show-annotation]
+  '(menu-item "Show Annotation" bookmark-bmenu-show-annotation
+    :help "Show the annotation for this bookmark (in another window)"
+    :enable (and (bookmark-bmenu-bookmark)  (bookmark-get-annotation (bookmark-bmenu-bookmark)))))
+(define-key bmkp-bmenu-show-menu [bookmark-bmenu-toggle-filenames]
+  '(menu-item "Show/Hide File Names" bookmark-bmenu-toggle-filenames
+    :help "Toggle whether filenames are shown in the bookmark list"))
+
+(define-key bmkp-bmenu-show-menu [show-sep5] '("--")) ; --------------
+(define-key bmkp-bmenu-show-menu [bmkp-bmenu-filter-tags-incrementally]
+  '(menu-item "Show Only Tag Matches..." bmkp-bmenu-filter-tags-incrementally
+    :help "Incrementally filter bookmarks by tags using a regexp"))
+(define-key bmkp-bmenu-show-menu [bmkp-bmenu-filter-annotation-incrementally]
+  '(menu-item "Show Only Annotation Matches..." bmkp-bmenu-filter-annotation-incrementally
+    :help "Incrementally filter bookmarks by annotation using a regexp"))
+(define-key bmkp-bmenu-show-menu [bmkp-bmenu-filter-file-name-incrementally]
+  '(menu-item "Show Only File Name Matches..." bmkp-bmenu-filter-file-name-incrementally
+    :help "Incrementally filter bookmarks by file name using a regexp"))
+(define-key bmkp-bmenu-show-menu [bmkp-bmenu-filter-bookmark-name-incrementally]
+  '(menu-item "Show Only Name Matches..." bmkp-bmenu-filter-bookmark-name-incrementally
+    :help "Incrementally filter bookmarks by bookmark name using a regexp"))
+
+(define-key bmkp-bmenu-show-menu [show-sep3] '("--")) ; --------------
+(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-specific-file-bookmarks]
+  '(menu-item "Show Only for Specific File" bmkp-bmenu-show-only-specific-file-bookmarks
+    :help "Display (only) the bookmarks for a specific file"))
+(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-specific-buffer-bookmarks]
+  '(menu-item "Show Only for Specific Buffer" bmkp-bmenu-show-only-specific-buffer-bookmarks
+    :help "Display (only) the bookmarks for a specific buffer"))
+
+(define-key bmkp-bmenu-show-menu [show-sep2] '("--")) ; --------------
+(when (featurep 'bookmark+-lit)
+  (define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-lighted-bookmarks]
+    '(menu-item "Show Only Highlighted" bmkp-bmenu-show-only-lighted-bookmarks
+      :help "Display (only) highlighted bookmarks")))
+(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-temporary-bookmarks]
+  '(menu-item "Show Only Temporaries" bmkp-bmenu-show-only-temporary-bookmarks
+    :help "Display (only) the temporary bookmarks (`X')"))
+(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-autonamed-bookmarks]
+  '(menu-item "Show Only Autonamed" bmkp-bmenu-show-only-autonamed-bookmarks
+    :help "Display (only) the autonamed bookmarks"))
+(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-autofile-bookmarks]
+  '(menu-item "Show Only Autofiles" bmkp-bmenu-show-only-autofile-bookmarks
+    :help "Display (only) the autofile bookmarks: those named the same as their files"))
+
+(define-key bmkp-bmenu-show-menu [show-sep1] '("--")) ; --------------
+(define-key bmkp-bmenu-show-menu [bmkp-bmenu-toggle-show-only-unmarked]
+  '(menu-item "Show Only Unmarked" bmkp-bmenu-toggle-show-only-unmarked
+    :help "Hide all marked bookmarks.  Repeat to toggle, showing all"))
+(define-key bmkp-bmenu-show-menu [bmkp-bmenu-toggle-show-only-marked]
+  '(menu-item "Show Only Marked" bmkp-bmenu-toggle-show-only-marked
+    :help "Hide all unmarked bookmarks.  Repeat to toggle, showing all"))
+(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-all]
+  '(menu-item "Show All" bmkp-bmenu-show-all
+    :help "Show all bookmarks currently known to the bookmark list"))
+
+
+;;; `Show' > `Only Bookmarks of Type' submenu -----------------------------
+
+(defvar bmkp-bmenu-show-types-menu (make-sparse-keymap "Only Bookmarks of Type")
+    "`Only Bookmarks of Type' submenu for `Show' submenu of `Bookmark+' menu.")
+(define-key bmkp-bmenu-show-menu [type] (cons "Only Bookmarks of Type" bmkp-bmenu-show-types-menu))
+
+(define-key bmkp-bmenu-show-types-menu [show-sep4] '("--")) ; --------------
+(define-key bmkp-bmenu-show-types-menu [bmkp-bmenu-show-only-w3m-bookmarks]
+  '(menu-item "W3M URLs" bmkp-bmenu-show-only-w3m-bookmarks
+    :help "Display (only) the W3M URL bookmarks"))
+(when (fboundp 'bmkp-bmenu-show-only-eww-bookmarks) ; Emacs 25+
+  (define-key bmkp-bmenu-show-types-menu [bmkp-bmenu-show-only-eww-bookmarks]
+    '(menu-item "EWW URLs" bmkp-bmenu-show-only-eww-bookmarks
+      :help "Display (only) the EWW URL bookmarks")))
+(define-key bmkp-bmenu-show-types-menu [bmkp-bmenu-show-only-url-bookmarks]
+  '(menu-item "URLs" bmkp-bmenu-show-only-url-bookmarks
+    :help "Display (only) the URL bookmarks"))
+(define-key bmkp-bmenu-show-types-menu [bmkp-bmenu-show-only-man-bookmarks]
+  '(menu-item "UNIX Manual Pages" bmkp-bmenu-show-only-man-bookmarks
+    :help "Display (only) the `man' page bookmarks"))
+(define-key bmkp-bmenu-show-types-menu [bmkp-bmenu-show-only-untagged-bookmarks]
+  '(menu-item "Untagged" bmkp-bmenu-show-only-untagged-bookmarks
+    :help "Display (only) the bookmarks that do not have tags"))
+(define-key bmkp-bmenu-show-types-menu [bmkp-bmenu-show-only-tagged-bookmarks]
+  '(menu-item "Tagged" bmkp-bmenu-show-only-tagged-bookmarks
+    :help "Display (only) the bookmarks that have tags"))
+(define-key bmkp-bmenu-show-types-menu [bmkp-bmenu-show-only-variable-list-bookmarks]
+  '(menu-item "Variable Lists" bmkp-bmenu-show-only-variable-list-bookmarks
+    :help "Display (only) the variable-list bookmarks"))
+(define-key bmkp-bmenu-show-types-menu [bmkp-bmenu-show-only-function-bookmarks]
+  '(menu-item "Functions" bmkp-bmenu-show-only-function-bookmarks
+    :help "Display (only) the function bookmarks"))
+(define-key bmkp-bmenu-show-types-menu [bmkp-bmenu-show-only-snippet-bookmarks]
+  '(menu-item "Snippets" bmkp-bmenu-show-only-snippet-bookmarks
+    :help "Display (only) the snippet bookmarks"))
+(define-key bmkp-bmenu-show-types-menu [bmkp-bmenu-show-only-region-bookmarks]
+  '(menu-item "Regions" bmkp-bmenu-show-only-region-bookmarks
+    :help "Display (only) the bookmarks that record a region"))
+(define-key bmkp-bmenu-show-types-menu [bmkp-bmenu-show-only-orphaned-local-file-bookmarks]
+  '(menu-item "Orphaned Local Files" bmkp-bmenu-show-only-orphaned-local-file-bookmarks
+    :help "Display (only) orphaned local-file bookmarks (`C-u': show remote also)"))
+(define-key bmkp-bmenu-show-types-menu [bmkp-bmenu-show-only-non-invokable-bookmarks]
+  '(menu-item "Non-Invokable" bmkp-bmenu-show-only-non-invokable-bookmarks
+    :help "Display (only) the non-invokable bookmarks"))
+(define-key bmkp-bmenu-show-types-menu [bmkp-bmenu-show-only-non-file-bookmarks]
+  '(menu-item "Non-Files (Buffers)" bmkp-bmenu-show-only-non-file-bookmarks
+    :help "Display (only) the non-file bookmarks"))
+(define-key bmkp-bmenu-show-types-menu [bmkp-bmenu-show-only-image-bookmarks]
+  '(menu-item "Image Files" bmkp-bmenu-show-only-image-bookmarks
+    :help "Display (only) image-file bookmarks"))
+(define-key bmkp-bmenu-show-types-menu [bmkp-bmenu-show-only-icicles-search-hits-bookmarks]
+  '(menu-item "Icicles Search-Hits" bmkp-bmenu-show-only-icicles-search-hits-bookmarks
+    :help "Display (only) Icicles search-hits bookmarks"))
+(define-key bmkp-bmenu-show-types-menu [bmkp-bmenu-show-only-info-bookmarks]
+  '(menu-item "Info Nodes" bmkp-bmenu-show-only-info-bookmarks
+    :help "Display (only) the Info bookmarks"))
+(define-key bmkp-bmenu-show-types-menu [bmkp-bmenu-show-only-gnus-bookmarks]
+  '(menu-item "Gnus Messages" bmkp-bmenu-show-only-gnus-bookmarks
+    :help "Display (only) the Gnus bookmarks"))
+(define-key bmkp-bmenu-show-types-menu [bmkp-bmenu-show-only-file-bookmarks]
+  '(menu-item "Files" bmkp-bmenu-show-only-file-bookmarks
+    :help "Display (only) the file and directory bookmarks"))
+(define-key bmkp-bmenu-show-types-menu [bmkp-bmenu-show-only-dired-bookmarks]
+  '(menu-item "Dired Buffers" bmkp-bmenu-show-only-dired-bookmarks
+    :help "Display (only) the Dired bookmarks"))
+(define-key bmkp-bmenu-show-types-menu [bmkp-bmenu-show-only-desktop-bookmarks]
+  '(menu-item "Desktops" bmkp-bmenu-show-only-desktop-bookmarks
+    :help "Display (only) the desktop bookmarks"))
+(define-key bmkp-bmenu-show-types-menu [bmkp-bmenu-show-only-bookmark-list-bookmarks]
+  '(menu-item "Bookmark Lists" bmkp-bmenu-show-only-bookmark-list-bookmarks
+    :help "Display (only) the bookmark-list bookmarks"))
+(define-key bmkp-bmenu-show-types-menu [bmkp-bmenu-show-only-bookmark-file-bookmarks]
+  '(menu-item "Bookmark Files" bmkp-bmenu-show-only-bookmark-file-bookmarks
+    :help "Display (only) the bookmark-file bookmarks"))
+
+
+;;; `Omit' submenu ---------------------------------------------------
+(define-key bmkp-bmenu-omit-menu [bmkp-bmenu-show-all]
+  '(menu-item "Show All" bmkp-bmenu-show-all
+    :visible (eq bmkp-bmenu-filter-function 'bmkp-omitted-alist-only)
+    :help "Show all bookmarks (except omitted)"))
+(define-key bmkp-bmenu-omit-menu [bmkp-bmenu-show-only-omitted-bookmarks]
+  '(menu-item "Show Only Omitted" bmkp-bmenu-show-only-omitted-bookmarks
+    :visible (not (eq bmkp-bmenu-filter-function 'bmkp-omitted-alist-only))
+    :enable bmkp-bmenu-omitted-bookmarks :help "Show only the omitted bookmarks"))
+(define-key bmkp-bmenu-omit-menu [bmkp-unomit-all]
+  '(menu-item "Un-Omit All" bmkp-unomit-all
+    :visible bmkp-bmenu-omitted-bookmarks :help "Un-omit all omitted bookmarks"))
+(define-key bmkp-bmenu-omit-menu [bmkp-bmenu-unomit-marked]
+  '(menu-item "Un-Omit Marked" bmkp-bmenu-unomit-marked
+    :visible (eq bmkp-bmenu-filter-function 'bmkp-omitted-alist-only)
+    :enable (and bmkp-bmenu-omitted-bookmarks
+             (save-excursion (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines)
+                             (re-search-forward "^>" (point-max) t)))
+    :help "Un-omit the marked bookmarks" :keys "\\[bmkp-bmenu-omit/unomit-marked]"))
+(define-key bmkp-bmenu-omit-menu [bmkp-bmenu-omit-marked]
+  '(menu-item "Omit Marked" bmkp-bmenu-omit-marked
+    :visible (not (eq bmkp-bmenu-filter-function 'bmkp-omitted-alist-only))
+    :enable (save-excursion (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines)
+                            (re-search-forward "^>" (point-max) t))
+    :help "Omit the marked bookmarks" :keys "\\[bmkp-bmenu-omit/unomit-marked]"))
+
+
+;;; `Mark' submenu ---------------------------------------------------
+(define-key bmkp-bmenu-mark-menu [mark-sep5] '("--")) ; --------------
+(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-load-marking-unmark-first]
+  '(menu-item "Load Bookmark File, Mark Only Loaded...." bmkp-bmenu-load-marking-unmark-first
+    :help "`bookmark-load', marking only bookmarks that are loaded."))
+(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-load-marking]
+  '(menu-item "Load Bookmark File, Mark Loaded...." bmkp-bmenu-load-marking
+    :help "`bookmark-load', but mark bookmarks that are loaded.  C-u: unmark all first."))
+
+(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-unmark-bookmarks-tagged-not-all]
+  '(menu-item "Unmark If Not Tagged with All..." bmkp-bmenu-unmark-bookmarks-tagged-not-all
+    :help "Unmark all visible bookmarks that are tagged with *some* tag in a set you specify"))
+(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-unmark-bookmarks-tagged-none]
+  '(menu-item "Unmark If Tagged with None..." bmkp-bmenu-unmark-bookmarks-tagged-none
+    :help "Unmark all visible bookmarks that are *not* tagged with *any* tag you specify"))
+(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-unmark-bookmarks-tagged-all]
+  '(menu-item "Unmark If Tagged with All..." bmkp-bmenu-unmark-bookmarks-tagged-all
+    :help "Unmark all visible bookmarks that are tagged with *each* tag you specify"))
+(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-unmark-bookmarks-tagged-some]
+  '(menu-item "Unmark If Tagged with Some..." bmkp-bmenu-unmark-bookmarks-tagged-some
+    :help "Unmark all visible bookmarks that are tagged with *some* tag in a set you specify"))
+(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-unmark-bookmarks-tagged-regexp]
+  '(menu-item "Unmark If Tagged Matching Regexp..." bmkp-bmenu-unmark-bookmarks-tagged-regexp
+    :help "Unmark bookmarks any of whose tags match a regexp you enter"))
+(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-bookmarks-tagged-not-all]
+  '(menu-item "Mark If Not Tagged with All..." bmkp-bmenu-mark-bookmarks-tagged-not-all
+    :help "Mark all visible bookmarks that are *not* tagged with *all* tags you specify"))
+(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-bookmarks-tagged-none]
+  '(menu-item "Mark If Tagged with None..." bmkp-bmenu-mark-bookmarks-tagged-none
+    :help "Mark all visible bookmarks that are not tagged with *any* tag you specify"))
+(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-bookmarks-tagged-all]
+  '(menu-item "Mark If Tagged with All..." bmkp-bmenu-mark-bookmarks-tagged-all
+    :help "Mark all visible bookmarks that are tagged with *each* tag you specify"))
+(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-bookmarks-tagged-some]
+  '(menu-item "Mark If Tagged with Some..." bmkp-bmenu-mark-bookmarks-tagged-some
+    :help "Mark all visible bookmarks that are tagged with *some* tag in a set you specify"))
+(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-bookmarks-tagged-regexp]
+  '(menu-item "Mark If Tagged Matching Regexp..." bmkp-bmenu-mark-bookmarks-tagged-regexp
+    :help "Mark bookmarks any of whose tags match a regexp you enter"))
+
+(define-key bmkp-bmenu-mark-menu [mark-sep3] '("--")) ; --------------
+(when (featurep 'bookmark+-lit)
+  (define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-lighted-bookmarks]
+    '(menu-item "Mark Highlighted" bmkp-bmenu-mark-lighted-bookmarks
+      :help "Mark highlighted bookmarks")))
+(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-temporary-bookmarks]
+  '(menu-item "Mark Temporaries" bmkp-bmenu-mark-temporary-bookmarks
+    :help "Mark temporary bookmarks (those with `X')"))
+(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-autonamed-bookmarks]
+  '(menu-item "Mark Autonamed" bmkp-bmenu-mark-autonamed-bookmarks
+    :help "Mark autonamed bookmarks"))
+(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-autofile-bookmarks]
+  '(menu-item "Mark Autofiles" bmkp-bmenu-mark-autofile-bookmarks
+    :help "Mark autofile bookmarks: those whose names are the same as their files"))
+
+(define-key bmkp-bmenu-mark-menu [mark-sep2] '("--")) ; --------------
+(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-unmark-all]
+  '(menu-item "Unmark All" bmkp-bmenu-unmark-all
+    :help "Remove a mark you specify (> or D) from each bookmark (RET to remove both kinds)"))
+(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-all]
+  '(menu-item "Mark All" bmkp-bmenu-mark-all :help "Mark all bookmarks, using mark `>'"))
+(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-toggle-marks]
+  '(menu-item "Toggle Marked/Unmarked" bmkp-bmenu-toggle-marks
+    :help "Unmark all marked bookmarks; mark all unmarked bookmarks"))
+(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-regexp-mark]
+  '(menu-item "Mark Regexp Matches..." bmkp-bmenu-regexp-mark
+    :help "Mark bookmarks that match a regexp that you enter"))
+
+(define-key bmkp-bmenu-mark-menu [mark-sep4] '("--")) ; --------------
+(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-specific-file-bookmarks]
+  '(menu-item "Mark for Specific File" bmkp-bmenu-mark-specific-file-bookmarks
+    :help "Mark bookmarks for a specific file"))
+(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-specific-buffer-bookmarks]
+  '(menu-item "Mark for Specific Buffer" bmkp-bmenu-mark-specific-buffer-bookmarks
+    :help "Mark bookmarks for a specific buffer"))
+
+
+;; `Mark' > `Bookmarks of Type' submenu ------------------------------
+(defvar bmkp-bmenu-mark-types-menu (make-sparse-keymap "Bookmarks of Type")
+  "`Bookmarks of Type' submenu for `Mark' submenu of m`Bookmark+' menu.")
+(define-key bmkp-bmenu-mark-menu [type] (cons "Bookmarks of Type" bmkp-bmenu-mark-types-menu))
+
+(define-key bmkp-bmenu-mark-types-menu [bmkp-bmenu-mark-w3m-bookmarks]
+  '(menu-item "W3M URLs" bmkp-bmenu-mark-w3m-bookmarks :help "Mark W3M URL bookmarks"))
+(when (fboundp 'bmkp-bmenu-mark-eww-bookmarks) ; Emacs 25+
+  (define-key bmkp-bmenu-mark-types-menu [bmkp-bmenu-mark-eww-bookmarks]
+    '(menu-item "EWW URLs" bmkp-bmenu-mark-eww-bookmarks :help "Mark Eww URL bookmarks")))
+(define-key bmkp-bmenu-mark-types-menu [bmkp-bmenu-mark-url-bookmarks]
+  '(menu-item "URLs" bmkp-bmenu-mark-url-bookmarks :help "Mark URL bookmarks"))
+(define-key bmkp-bmenu-mark-types-menu [bmkp-bmenu-mark-variable-list-bookmarks]
+  '(menu-item "Variable Lists" bmkp-bmenu-mark-variable-list-bookmarks
+    :help "Mark the variable-list bookmarks"))
+(define-key bmkp-bmenu-mark-types-menu [bmkp-bmenu-mark-man-bookmarks]
+  '(menu-item "UNIX Manual Pages" bmkp-bmenu-mark-man-bookmarks
+    :help "Mark `man' page bookmarks"))
+(define-key bmkp-bmenu-mark-types-menu [bmkp-bmenu-mark-snippet-bookmarks]
+  '(menu-item "Snippets" bmkp-bmenu-mark-snippet-bookmarks
+    :help "Mark snippet bookmarks"))
+(define-key bmkp-bmenu-mark-types-menu [bmkp-bmenu-mark-region-bookmarks]
+  '(menu-item "Regions" bmkp-bmenu-mark-region-bookmarks
+    :help "Mark bookmarks that record a region"))
+(define-key bmkp-bmenu-mark-types-menu [bmkp-bmenu-mark-orphaned-local-file-bookmarks]
+  '(menu-item "Orphaned Local Files" bmkp-bmenu-mark-orphaned-local-file-bookmarks
+    :help "Mark orphaned local-file bookmarks (`C-u': remote also)"))
+(define-key bmkp-bmenu-mark-types-menu [bmkp-bmenu-mark-non-invokable-bookmarks]
+  '(menu-item "Non-Invokable" bmkp-bmenu-mark-non-invokable-bookmarks
+    :help "Mark non-invokable bookmarks"))
+(define-key bmkp-bmenu-mark-types-menu [bmkp-bmenu-mark-non-file-bookmarks]
+  '(menu-item "Non-Files (Buffers)" bmkp-bmenu-mark-non-file-bookmarks
+    :help "Mark non-file bookmarks"))
+(define-key bmkp-bmenu-mark-types-menu [bmkp-bmenu-mark-image-bookmarks]
+  '(menu-item "Images" bmkp-bmenu-mark-image-bookmarks :help "Mark image-file bookmarks"))
+(define-key bmkp-bmenu-mark-types-menu [bmkp-bmenu-mark-icicles-search-hits-bookmarks]
+  '(menu-item "Icicle Search Hits" bmkp-bmenu-mark-icicles-search-hits-bookmarks
+    :help "Mark Icicles search-hit bookmarks"))
+(define-key bmkp-bmenu-mark-types-menu [bmkp-bmenu-mark-info-bookmarks]
+  '(menu-item "Info Nodes" bmkp-bmenu-mark-info-bookmarks :help "Mark Info bookmarks"))
+(define-key bmkp-bmenu-mark-types-menu [bmkp-bmenu-mark-gnus-bookmarks]
+  '(menu-item "Gnus Messages" bmkp-bmenu-mark-gnus-bookmarks :help "Mark Gnus bookmarks"))
+(define-key bmkp-bmenu-mark-types-menu [bmkp-bmenu-mark-file-bookmarks]
+  '(menu-item "Files" bmkp-bmenu-mark-file-bookmarks :help "Mark file bookmarks"))
+(define-key bmkp-bmenu-mark-types-menu [bmkp-bmenu-mark-dired-bookmarks]
+  '(menu-item "Dired Buffers" bmkp-bmenu-mark-dired-bookmarks :help "Mark Dired bookmarks"))
+(define-key bmkp-bmenu-mark-types-menu [bmkp-bmenu-mark-desktop-bookmarks]
+  '(menu-item "Desktops" bmkp-bmenu-mark-desktop-bookmarks
+    :help "Mark desktop bookmarks"))
+(define-key bmkp-bmenu-mark-types-menu [bmkp-bmenu-mark-bookmark-list-bookmarks]
+  '(menu-item "Bookmark Lists" bmkp-bmenu-mark-bookmark-list-bookmarks
+    :help "Mark the bookmark-list bookmarks"))
+(define-key bmkp-bmenu-mark-types-menu [bmkp-bmenu-mark-bookmark-file-bookmarks]
+  '(menu-item "Bookmark Files" bmkp-bmenu-mark-bookmark-file-bookmarks
+    :help "Mark the bookmark-file bookmarks"))
+
+
+;;; `Delete' submenu -------------------------------------------------
+(define-key bmkp-bmenu-delete-menu [bookmark-bmenu-execute-deletions]
+  '(menu-item "Delete Flagged (D)..." bookmark-bmenu-execute-deletions
+    :help "Delete the (visible) bookmarks flagged `D'"))
+(define-key bmkp-bmenu-delete-menu [bmkp-bmenu-delete-marked]
+  '(menu-item "Delete Marked (>)..." bmkp-bmenu-delete-marked
+    :help "Delete all (visible) bookmarks marked `>', after confirmation"))
+(define-key bmkp-bmenu-delete-menu [bmkp-delete-all-temporary-bookmarks]
+  '(menu-item "Delete All Temporaries..." bmkp-delete-all-temporary-bookmarks
+    :help "Delete the temporary bookmarks, (`X') whether visible here or not"))
+
+
+;;; `Edit' menu-bar menu
+
+;; `menu-bar+.el' redefines `menu-bar-edit-menu'.
+;; Soft-require it in `condition-case' because it soft-requires Bookmark+.
+(condition-case nil (require 'menu-bar+ nil t) (error nil))
+
+(define-key-after menu-bar-edit-menu [separator-snippet] '("--")  'mark-whole-buffer)
+(define-key-after menu-bar-edit-menu [bmkp-set-snippet-bookmark]
+  '(menu-item "Region to Snippet..." bmkp-set-snippet-bookmark
+    :help "Save the region text to a snippet bookmark"
+    :enable (and mark-active (not buffer-read-only))) 'separator-snippet)
+(define-key-after menu-bar-edit-menu [bmkp-snippet-to-kill-ring]
+  '(menu-item "Snippet to Kill Ring..." bmkp-snippet-to-kill-ring
+    :help "Copy the text saved in a snippet bookmark to the `kill-ring'")
+  'bmkp-set-snippet-bookmark)
+
+
+
+;;;---------------------------------------------------------------------------------------
+
+;;; Mouse-3 menu binding.
+
+(defvar bmkp-bmenu-line-overlay nil
+  "Overlay to highlight the current line for `bmkp-bmenu-mouse-3-menu'.")
+(define-key bookmark-bmenu-mode-map [down-mouse-3] 'bmkp-bmenu-mouse-3-menu)
+(define-key bookmark-bmenu-mode-map [mouse-3]      'ignore)
+
+;;;###autoload (autoload 'bmkp-bmenu-mouse-3-menu "bookmark+")
+(defun bmkp-bmenu-mouse-3-menu (event)
+  "Pop-up menu on `mouse-3' for a bookmark listed in `*Bookmark List*'."
+  (interactive "e")
+  (let* ((mouse-pos                  (event-start event))
+         (inhibit-field-text-motion  t) ; Just in case.
+         bol eol bmk-name)
+    (with-current-buffer (window-buffer (posn-window mouse-pos))
+      (save-excursion
+        (goto-char (posn-point mouse-pos))
+        (setq bol  (line-beginning-position)
+              eol  (line-end-position))
+        (unwind-protect
+             (progn
+               (if bmkp-bmenu-line-overlay ; Don't re-create.
+                   (move-overlay bmkp-bmenu-line-overlay bol eol (current-buffer))
+                 (setq bmkp-bmenu-line-overlay  (make-overlay bol eol))
+                 (overlay-put bmkp-bmenu-line-overlay 'face 'region))
+               (setq bmk-name (bookmark-bmenu-bookmark))
+               (when bmk-name
+                 (sit-for 0)
+                 (let* ((map     (easy-menu-create-menu
+                                  "This Bookmark"
+                                  `(,(if (bmkp-bookmark-name-member bmk-name bmkp-bmenu-marked-bookmarks)
+                                         ["Unmark" bookmark-bmenu-unmark]
+                                         ["Mark" bookmark-bmenu-mark])
+                                    ,(save-excursion
+                                      (goto-char (posn-point mouse-pos))
+                                      (beginning-of-line)
+                                      (if (bmkp-looking-at-p "^D")
+                                          ["Unmark" bookmark-bmenu-unmark]
+                                        ["Flag for Deletion" bmkp-bmenu-flag-for-deletion]))
+                                    ["Omit" bmkp-bmenu-omit]
+                                    ["Jump To" bookmark-bmenu-this-window]
+                                    ["Jump To in Other Window" bookmark-bmenu-other-window]
+
+                                    "--" ; ----------------------------------------------------
+                                    ["Edit Tags..." bmkp-bmenu-edit-tags
+                                     :active (bmkp-get-tags bmk-name)]
+                                    ["Copy Tags" bmkp-bmenu-copy-tags
+                                     ;; You can copy an empty list of tags and paste-replace with it.
+                                     ;; :active (bmkp-get-tags bmk-name)
+                                     ]
+                                    ["Paste Tags (Add)" bmkp-bmenu-paste-add-tags
+                                     :active bmkp-copied-tags]
+                                    ["Paste Tags (Replace)" bmkp-bmenu-paste-replace-tags
+                                     ;; You can paste an empty list of tags to replace tags.
+                                     ;; :active bmkp-copied-tags
+                                     ]
+                                    ["Add Some Tags..." bmkp-bmenu-add-tags]
+                                    ["Remove Some Tags..." bmkp-bmenu-remove-tags
+                                     :active (bmkp-get-tags bmk-name)]
+                                    ["Remove All Tags..." bmkp-bmenu-remove-all-tags
+                                     :active (bmkp-get-tags bmk-name)]
+                                    ["Set Tag Value..." bmkp-bmenu-set-tag-value
+                                     :active (bmkp-get-tags bmk-name)]
+                                    ["Rename Tag..." bmkp-rename-tag
+                                     :active (bmkp-get-tags bmk-name)]
+
+                                    ["--" 'ignore :visible (featurep 'bookmark+-lit)] ; ---------------
+                                    ["Highlight" bmkp-bmenu-light
+                                     :visible (featurep 'bookmark+-lit)
+                                     :active (not (bmkp-lighted-p bmk-name))]
+                                    ["Unhighlight" bmkp-bmenu-unlight
+                                     :visible (featurep 'bookmark+-lit)
+                                     :active (bmkp-lighted-p bmk-name)]
+                                    ["Set Lighting" bmkp-bmenu-set-lighting
+                                     :visible (featurep 'bookmark+-lit)]
+
+                                    "--" ; ----------------------------------------------------
+                                    ["Toggle Temporary/Savable" bmkp-bmenu-toggle-temporary]
+                                    ,@(and (fboundp 'org-add-link-type)
+                                           '(["Store Org Link" org-store-link]))
+                                    ["Rename or Relocate..." bmkp-bmenu-edit-bookmark-name-and-location]
+                                    ["Clone (Duplicate)" bmkp-bmenu-clone-bookmark]
+                                    ["Edit Internal Record (Lisp)..." bmkp-bmenu-edit-bookmark-record]
+                                    ["Show Annotation" bookmark-bmenu-show-annotation
+                                     :active (bookmark-get-annotation bmk-name)]
+                                    ["Edit Annotation..." bookmark-bmenu-edit-annotation]
+
+                                    "--" ; ----------------------------------------------------
+                                    ["Describe" bmkp-bmenu-describe-this-bookmark])))
+                        (choice  (x-popup-menu event map)))
+                   (when choice
+                     (call-interactively (lookup-key map (apply 'vector choice)))))))
+          (when bmkp-bmenu-line-overlay (delete-overlay bmkp-bmenu-line-overlay)))))))
+
+;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'bookmark+-bmu)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; bookmark+-bmu.el ends here
diff --git a/lisp/bookmark+-chg.el b/lisp/bookmark+-chg.el
new file mode 100644 (file)
index 0000000..3c8653b
--- /dev/null
@@ -0,0 +1,3703 @@
+;;; bookmark+-chg.el - Change logs for Bookmark+ libraries.
+;;
+;; Filename: bookmark+-chg.el
+;; Description: Change logs for Bookmark+ libraries.
+;; Author: Drew Adams
+;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com")
+;; Copyright (C) 2000-2022, Drew Adams, all rights reserved.
+;; Created: Fri Sep 15 07:58:41 2000
+;; Last-Updated: Fri Jan 14 12:54:17 2022 (-0800)
+;;           By: dradams
+;;     Update #: 16855
+;; URL: https://www.emacswiki.org/emacs/download/bookmark%2b-chg.el
+;; Doc URL: https://www.emacswiki.org/emacs/BookmarkPlus
+;; Keywords: bookmarks, bookmark+
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x, 24.x, 25.x, 26.
+;; Features that might be required by this library:
+;;
+;;   None
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;    Change log for the Bookmark+ libraries, which extend standard
+;;    library `bookmark.el'.  This file contains no code, so you need
+;;    not load it.
+;;
+;;    The Bookmark+ libraries are these:
+;;
+;;    `bookmark+.el'     - main (driver) code library
+;;    `bookmark+-mac.el' - Lisp macros
+;;    `bookmark+-lit'    - (optional) code for highlighting bookmarks
+;;    `bookmark+-bmu.el' - code for the `*Bookmark List*' (bmenu)
+;;    `bookmark+-1.el'   - other (non-bmenu) required code
+;;    `bookmark+-key.el' - key and menu bindings
+;;
+;;    `bookmark+-doc'    - documentation (comment-only file)
+;;    `bookmark+-chg'    - change log (this file)
+;;
+;;    The documentation (in `bookmark+-doc.el') includes how to
+;;    byte-compile and install Bookmark+.  The documentation is also
+;;    available in these ways:
+;;
+;;    1. From the bookmark list (`C-x r l'):
+;;       Use `?' to show the current bookmark-list status and general
+;;       help, then click link `Doc in Commentary' or link `Doc on the
+;;       Web'.
+;;
+;;    2. From the Emacs-Wiki Web site:
+;;       https://www.emacswiki.org/emacs/BookmarkPlus.
+;;
+;;    3. From the Bookmark+ group customization buffer:
+;;       `M-x customize-group bookmark-plus', then click link
+;;       `Commentary'.
+;;
+;;    (The commentary links in #1 and #3 work only if you put library
+;;    `bookmark+-doc.el' in your `load-path'.)
+;;
+;;
+;;    ****** NOTE ******
+;;
+;;      WHENEVER you update Bookmark+ (i.e., download new versions of
+;;      Bookmark+ source files), I recommend that you do the
+;;      following:
+;;
+;;      1. Delete ALL existing BYTE-COMPILED Bookmark+ files
+;;         (bookmark+*.elc).
+;;      2. Load Bookmark+ (`load-library' or `require').
+;;      3. Byte-compile the source files.
+;;
+;;      In particular, ALWAYS LOAD `bookmark+-mac.el' (not
+;;      `bookmark+-mac.elc') BEFORE YOU BYTE-COMPILE new versions of
+;;      the files, in case there have been any changes to Lisp macros
+;;      (in `bookmark+-mac.el').
+;;
+;;      (This is standard procedure for Lisp: code that depends on
+;;      macros needs to be byte-compiled anew after loading the
+;;      updated macros.)
+;;
+;;    ******************
+;;
+;;
+;;    ****** NOTE ******
+;;
+;;      On 2010-06-18, I changed the prefix used by package Bookmark+
+;;      from `bookmarkp-' to `bmkp-'.  THIS IS AN INCOMPATIBLE CHANGE.
+;;      I apologize for the inconvenience, but the new prefix is
+;;      preferable for a number of reasons, including easier
+;;      distinction from standard `bookmark.el' names.
+;;
+;;      This change means that YOU MUST MANUALLY REPLACE ALL
+;;      OCCURRENCES of `bookmarkp-' by `bmkp-' in the following
+;;      places, if you used Bookmark+ prior to this change:
+;;
+;;      1. In your init file (`~/.emacs') or your `custom-file', if
+;;         you have one.  This is needed if you customized any
+;;         Bookmark+ features.
+;;
+;;      2. In your default bookmark file, `bookmark-default-file'
+;;         (`.emacs.bmk'), and in any other bookmark files you might
+;;         have.
+;;
+;;      3. In your `*Bookmark List*' state file,
+;;         `bmkp-bmenu-state-file' (`~/.emacs-bmk-bmenu-state.el').
+;;
+;;      4. In your `*Bookmark List*' commands file,
+;;         `bmkp-bmenu-commands-file' (`~/.emacs-bmk-bmenu-commands.el'),
+;;         if you have one.
+;;
+;;      You can do this editing in a virgin Emacs session (`emacs
+;;      -Q'), that is, without loading Bookmark+.
+;;
+;;      Alternatively, you can do this editing in an Emacs session
+;;      where Bookmark+ has been loaded, but in that case you must
+;;      TURN OFF AUTOMATIC SAVING of both your default bookmark file
+;;      and your `*Bookmark List*' state file.  Otherwise, when you
+;;      quit Emacs your manually edits will be overwritten.
+;;
+;;      To turn off this automatic saving, you can use `M-~' and `M-l'
+;;      in buffer `*Bookmark List*' (commands
+;;      `bmkp-toggle-saving-bookmark-file' and
+;;      `bmkp-toggle-saving-menu-list-state' - they are also in the
+;;      `Bookmark+' menu).
+;;
+;;
+;;      Again, sorry for this inconvenience.
+;;
+;;    ******************
+ 
+;;(@> "Index")
+;;
+;;  If you have library `linkd.el' and Emacs 22 or later, load
+;;  `linkd.el' and turn on `linkd-mode' now.  It lets you easily
+;;  navigate around the sections of this doc.  Linkd mode will
+;;  highlight this Index, as well as the cross-references and section
+;;  headings throughout this file.  You can get `linkd.el' here:
+;;  https://www.emacswiki.org/emacs/download/linkd.el.
+;;
+;;  (@> "CHANGE LOG FOR `bookmark+-1.el'")
+;;  (@> "CHANGE LOG FOR `bookmark+-bmu.el'")
+;;  (@> "CHANGE LOG FOR `bookmark+-doc.el'")
+;;  (@> "CHANGE LOG FOR `bookmark+-key.el'")
+;;  (@> "CHANGE LOG FOR `bookmark+-lit.el'")
+;;  (@> "CHANGE LOG FOR `bookmark+-mac.el'")
+;;  (@> "CHANGE LOG FOR `bookmark+.el'")
+ 
+;;;(@* "CHANGE LOG FOR `bookmark+-1.el'")
+;;
+;; 2021/09/19 dadams
+;;     Everywhere: Use bmkp-bmenu-buffer, not vanilla bookmark-bmenu-buffer.
+;;     bmkp-bmenu-barf-if-not-in-menu-list: Test mode with derived-mode-p; don't test buffer name.
+;; 2020/08/21 dadams
+;;     bookmark-set: Moved making bmk temporary before bookmark-store, and pass RECORD, not BNAME.
+;;     bmkp(*)-automatic*: Put defvaralias symbols in right order.
+;; 2021/08/18 dadams
+;;     Added: bmkp-set-automatic-bookmark.
+;;     Renamed: bmkp(*)-auto-idle* to bmkp(*)-automatic*.  Added defvaralias for old names.
+;; 2021/04/18 dadams
+;;     Added back a redefinition of bookmark-get-bookmark, as bmkp-get-bookmark with NO-NAME-CHECK-P.
+;;     bookmark-set-name, bookmark-location:
+;;       Replaced (bmkp-get-bookmark BMK nil 'NO-NAME-CHECK-P) with (bookmark-get-bookmark BMK).
+;;     Doc string and comment improvements, vis a vis uses of bookmark|bmkp-get-bookmark.
+;; 2021/04/16 dadams
+;;     bookmark-get-bookmark-record, bookmark-set-name, bookmark-prop-set, bookmark-location,
+;;       bookmark-delete, bookmark-show-annotation:
+;;         Use bmkp-get-bookmark, not bookmark-get-bookmark, but in vanilla-compatible way.
+;; 2021/04/13 dadams
+;;     Added: bmkp-get-bookmark.  Removed redefinition of vanilla bookmark-get-bookmark.
+;;       Problem was that some 3rd-party code uses bookmark-prop-set with unfinished bookmark record
+;;       that has no name.  Thx to Daniel Fleischer.
+;;     bookmark-prop-set: Added optional arg REQUIRE-NAME-P.  Pass it to bmkp-get-bookmark.
+;;     bookmark-handle-bookmark, bookmark-default-handler, bmkp-jump-1,
+;;      bmkp-show-this-annotation-read-only, bmkp-edit-this-annotation, bmkp-clone-bookmark,
+;;      bmkp-update-autonamed-bookmark, bmkp-*-bookmark-p, bmkp-*-(c)p, bmkp-insert-bookmark-link,
+;;      bmkp-describe-bookmark(-internals), bmkp-bookmark-description, bmkp-handle-region-default,
+;;      bmkp-set-sequence-bookmark, bmkp-set-eww-bookmark-here, bmkp-jump-man,
+;;      bmkp-cycle(-1|-this-(file|buffer)):
+;;        Use bmkp-get-bookmark, not bookmark-get-bookmark.
+;; 2021/03/17 dadams
+;;      Use buffer-string, not buffer-substring, for whole buffer.
+;; 2021/03/09 dadams
+;;     bmkp-handle-region-default: Set region and activate it at the end.
+;; 2021/03/05 dadams
+;;     Added: bmkp-read-buffers, bmkp-read-files.
+;;     bmkp(autofile|file(-this-dir))-(all|some)-tags(-regexp)-alist-only,
+;;       bmkp-specific-(buffers|files)-alist-only: Put property bmkp-read-arg with read-fn value.
+;;     bmkp-read-regexp: Made PROMPT arg optional.
+;;     bmkp-specific-(buffers|files)-jump(-other-window): Use bmkp-read-(buffers|files).
+;;     bmkp-set-autonamed-regexp-(buffer|region): Removed prompt from call to bmkp-read-regexp.
+;;     bmkp-annotate-bookmark-this-file/buffer, bmkp-edit-bookmark-record-file/buffer:
+;;       Fixed format spec.
+;; 2021/03/04 dadams
+;;     Added bmkp-types-alist.  The def is also in bookmark+-mac.el.
+;; 2020/11/28 dadams
+;;     Removed:
+;;       bmkp-bookmark-type-valid-p, variable (defconst) bmkp-types-alist, and all history variables.
+;;     Replaced all occurrences of variable bmkp-types-alist with function bmkp-types-alist.
+;;     Invoke macro bmkp-define-history-variables to define history vars, after defining filter fns.
+;;     Moved filter-function definitions to beginning of Bookmark+ functions section.
+;;     bmkp-edit-tags-send: Don't use bmkp-bookmark-type-valid-p - needs to work with unknown types.
+;; 2020/11/23 dadams
+;;     bmkp-url-target-set: Use read-from-minibuffer, not read-file-name, as fallback if no ffap.
+;;                          TEMPORARILY work around Emacs bug #44822 with phony default URL.
+;; 2020/08/30 dadams
+;;     Added: Info-bookmark-use-only-node-not-file-flag, redefinition of Info-bookmark-jump.
+;; 2020/07/04 dadams
+;;     Same commands as 7/03: Remove bmkp-propertize-*-flag as part of test for getting full bmk.
+;;     Changed all references to `C-x p' to `C-x x'.
+;;     Replaced string *Bookmark List* with bookmark-bmenu-buffer (for Emacs 28).
+;;     bookmark-(edit|show)-annotation, bmkp-annotate-bookmark,
+;;       bmkp-(edit|show)-this-annotation(-read-only):
+;;         Replaced set make-local-variable bookmark-annotation-name by setq (auto-local in Emacs 28).
+;; 2020/07/03 dadams
+;;     bmkp-read-bookmark-for-type:
+;;       Use bmkp-bookmark-record-from-name to return full bookmark from ALIST.
+;;     bmkp-(choose-navlist-from-bookmark-list|bookmark-file(-load|-switch)-jump|
+;;       snippet-to-kill-ring|desktop-delete|
+;;       (autonamed(-*)|dired(-*)|eww|(local|remote(-*)-|non-dir-)file(-*)|gnus|image|info|man|
+;;       non-file|specific-(buffers|files)|temporary|this-buffer|url|w3m|autofile)-jump*|
+;;       (bookmark-list|desktop|variable-list|w32-browser)-jump):
+;;         Use bmkp-get-bookmark-in-alist to get full bmk.
+;;     bmkp-jump-to-type*: Raise error if bookmark name, not record.
+;; 2020/07/02 dadams
+;;     bmkp-specific-files-alist-only: Don't use member, use bmkp-same-file-p as equality test.
+;; 2020/06/20 dadams
+;;     Added: bmkp-set-grep-command-bookmark.
+;; 2020/01/31 dadams
+;;     bmkp-dired-remember-*-marks:
+;;       Wrap dired--unhide with with-silent-modifications.  Thx to Tino Calancha. 
+;; 2020/01/26 dadams
+;;     Added: bmkp-annotated-cp.
+;; 2020/01/25 dadams
+;;     Added: bmkp-edit-bookmark-record-file/buffer.
+;; 2020/01/24 dadams
+;;     Added: bmkp-annotate-bookmark-this-file/buffer, bmkp-annotate-all-bookmarks-this-file/buffer.
+;; 2020/01/22 dadams
+;;     Added: bmkp-write-alist-bookmarks-to-file, bmkp-save-bookmarks-this-file/buffer,
+;;            bmkp-switch-to-bookmark-file-this-file/buffer.
+;;     bmkp-switch-bookmark-file-create: Added optional arg SWITCH-TO-LASTP (C-u behavior).
+;;     bmkp-save-menu-list-state: Save also last-previous-bookmark-file.
+;; 2020/01/15 dadams
+;;     bmkp-specific-files-alist-only: If no FILES arg and buffer is not visiting a file, use ().
+;; 2020/01/12 dadams
+;;     Added: bmkp-make-obsolete, bmkp-make-obsolete-variable.  Use everywhere instead of vanilla.
+;;     bookmark-completing-read, bmkp-completing-read-(1|bookmarks|lax):
+;;       Added optional arg USE-NIL-ALIST-P.
+;;     bmkp-completing-read-1: Made all args except PROMPT optional.
+;;     Protect defvaralias for bmkp-w3m-allow-multi-tabs-flag, for Emacs 20-21.
+;;     bookmark-edit-annotation: If no prefix arg, pass non-nil USE-NIL-ALIST-P arg.
+;;     bookmark-set: If numeric prefix arg, pass non-nil USE-NIL-ALIST-P arg.
+;;     bookmark-show-annotation, bmkp-retrieve-icicle-search-hits-1, bmkp-set-sequence-bookmark:
+;;       Pass non-nil USE-NIL-ALIST-P arg.
+;;     Renamed bmkp-bookmark-valid-p to bmkp-bookmark-type-valid-p.
+;;     bmkp-bookmark-type-valid-p: Restored missing definition (was bmkp-bookmark-type).
+;; 2019/08/13 dadams
+;;     Added bmkp-clone-bookmark, bmkp-copy-bookmark (alias).
+;; 2019/07/13 dadams
+;;     bookmark-edit-annotation: Added &rest _IGNORED, to accommodate vanilla change for bug #20150.
+;; 2019/06/08 dadams
+;;     bmkp-set-kmacro-bookmark: Do not use read-kbd-macro.
+;;     bmkp-repeat-command: Same as in zz-repeat-command in zones.el now.
+;;       Require repeat.el.  Bind repeat-previous-repeated-command.
+;;     bmkp-(next|previous)(-*)-bookmark(-*)-repeat: Removed require of repeat.el. 
+;; 2019/05/21 dadams
+;;     bmkp-dired-remember-*-marks: Updated per dired-remember-marks, for Emacs 27+.
+;; 2019/05/19 dadams
+;;     Bind print-gensym wherever we bind print-circle.
+;; 2019/05/11 dadams
+;;     Added bmkp-jump-to-list-button button type.  Forgot it on 2019-05-02.
+;; 2019/05/09 dadams
+;;     bmkp-this-buffer-bmenu-list: Call bookmark-maybe-load-default-file at outset.
+;; 2019/05/02 dadams
+;;     Added: bmkp-add-jump-to-list-button.
+;;     bmkp-describe-bookmark(-internals): Use bmkp-add-jump-to-list-button.
+;; 2019/05/01 dadams
+;;     Added bmkp-jump-to-list.
+;; 2019/04/23 dadams
+;;     Added bmkp-annotation-or-bookmark-description, bmkp-propertize.
+;; 2019/04/21 dadams
+;;     bmkp-temporary-bookmarking-mode: When enable mode reset bmkp-temporary-bookmarking-mode to nil.
+;; 2019/02/18
+;;     bmkp-autofile-bookmark-p, bmkp-file-target-set, bmkp-autofile-add-tags,
+;;       bmkp-get-autofile-bookmark:
+;;         Handle a directory like a file.
+;; 2018/12/23 dadams
+;;     Added: bmkp-bookmark-type-valid-p, bmkp-buffer-bookmark-p, bmkp-buffer-alist-only.
+;;     Removed: bmkp-bookmark-type - use bmkp-bookmark-type-valid-p instead.
+;;     bmkp-edit-tags-send: Use bmkp-bookmark-type-valid-p.
+;; 2018/11/22 dadams
+;;     bookmark-load: Return the list of bookmarks read from FILE.
+;;     bmkp-set-izones-bookmark: Include zone EXTRA info in bookmark record.
+;; 2018/11/09 dadams
+;;     Removed: bmkp-line-number-at-pos (not used).
+;; 2018/10/10 dadams
+;;     Added: bookmark-jump-other-frame.
+;; 2018/09/21 dadams
+;;     bmkp-show-this-annotation-read-only, bmkp-edit-this-annotation, bmkp-desktop-read,
+;;       bmkp-jump-man, bmkp-jump-dired, bmkp-jump-to-type, bmkp-*-jump, bmkp-jump-in-navlist:
+;;         Use bmkp--pop-to-buffer-same-window, not switch-to-buffer.
+;;       bmkp-image-jump-other-window, bmkp-autofile-jump-other-window:
+;;         Use bmkp-select-buffer-other-window, not switch-to-buffer (typo).
+;; 2018/08/30 dadams
+;;     Added defmacro for with-coding-priority at compile time.
+;; 2018/04/24 dadams
+;;     Added: bmkp-cycle-eww, bmkp-cycle-eww-other-window, bmkp-next-eww-bookmark,
+;;       bmkp-next-eww-bookmark-other-window, bmkp-next-eww-bookmark-other-window-repeat,
+;;       bmkp-next-eww-bookmark-repeat, bmkp-previous-eww-bookmark,
+;;       bmkp-previous-eww-bookmark-other-window, bmkp-previous-eww-bookmark-other-window-repeat,
+;;       bmkp-previous-eww-bookmark-repeat.
+;; 2018/04/22 dadams
+;;     Added: bmkp-bookmark-file-load-jump, bmkp-bookmark-file-switch-jump.  Not bound to keys.
+;; 2018/02/23 dadams
+;;     Changes to EWW support - thx to Charles Roelli.
+;;      Added: bmkp-eww-generate-buffer-flag.
+;;      Removed: bmkp-jump-eww-in-buffer-*eww*, bmkp-jump-eww-renaming-buffer,
+;;               bmkp-eww-sans-pop-to-buffer, bmkp-get-eww-mode-buffer.
+;;      Renamed: bmkp-eww-buffer-handling to bmkp-eww-buffer-renaming.
+;;      bmkp-eww-new-buf-name and bmkp-eww-jumping-p are now buffer-local.
+;;      bmkp-jump-eww: Respect bmkp-eww-generate-buffer-flag.  Use buffer-local eww-after-render-hook.
+;;                     Integrate code from removed functions.
+;;      bmkp-eww-rename-buffer: Rename to generated name if rename attempt fails and either
+;;                              bmkp-eww-generate-buffer-flag or not bmkp-eww-jumping-p.
+;; 2018/02/12 dadams
+;;     bookmark-write-file, bmkp-regexp-filtered-bookmark-name-alist-only:
+;;      Use bookmark-name-from-full-record, not car.
+;; 2018/02/10 dadams
+;;     bookmark-rename: No need to propertize name here - done in call to bookmark-set-name.
+;;     bookmark-alist-from-buffer: Use bmkp-bookmark-name-from-record, not car.
+;; 2017/11/27 dadams
+;;     bookmark-write-file:
+;;       Corrected change made on 2017/01/10 (fix for bug #25365).
+;;       Bind Lisp mode hooks to nil, to avoid inserting a Lisp file header for existing empty file.
+;; 2017/10/31 dadams
+;;     bookmark-send-edited-annotation: test using following-char, not bmkp-looking-at-p.
+;;     bookmark-save: Non-nil FILE now means use FILE, regardless of PARG value.
+;; 2017/10/08 dadams
+;;     bmkp-bookmark-description, bmkp-describe-bookmark-internals:
+;;       Bind print-(circle|length|level) so pp-to-string prints all.
+;; 2017/07/31 dadams
+;;     bmkp-find-file-invoke-bookmark-if-autofile:
+;;       Bind bmkp-autofile-access-invokes-bookmark-flag to nil while jumping to the bookmark.
+;; 2017/07/30 dadams
+;;     Added: bmkp-autofile-access-invokes-bookmark-flag, bmkp-find-file-invoke-bookmark-if-autofile.
+;;     bmkp-get-bookmark-in-alist: Use arg ALIST (was neglected).
+;; 2017/07/19 dadams
+;;     Put back bmkp-info-cp, as an obsolete alias, temporarily.
+;; 2017/07/03 dadams
+;;     Added: bmkp-info-position-cp, bmkp-info-sort-ignores-directories-flag.
+;;     Renamed: bmkp-info-cp to bmkp-info-node-name-cp.
+;;     bmkp-sort-comparer: Applied renaming of bmkp-info-cp.
+;;     bmkp-info-node-name-cp: Respect bmkp-info-sort-ignores-directories-flag (default: manual names)
+;; 2017/06/26 dadams
+;;     Added: bmkp-kmacro-list-bookmark-p.
+;;     bmkp-bookmark-description: Handle bmkp-kmacro-list-bookmark-p.
+;; 2017/06/25 dadams
+;;     Added: bmkp-set-kmacro-bookmark, bmkp-set-kmacro-list-bookmark, bmkp-jump-kmacro-list,
+;;            bmkp-make-kmacro-list-record.
+;; 2017/05/12 dadams
+;;     Added: bmkp-eww-auto-bookmark-mode, bmkp-set-eww-bookmark-here, bmkp-toggle-eww-auto-type,
+;;            bmkp-eww-auto-type.  Thx to Charles Roelli.
+;; 2017/03/31 dadams
+;;     Added other-window versions of: bmkp-(next|previous)(TYPE)-bookmark(-repeat).
+;;     bmkp-autonamed-bookmark-p:
+;;       If BUFFER is nil then let ?B match any name - do not use current buffer for nil case.
+;;     bmkp-goto-position: Error now mentions buffer name, not just file.
+;;     bmkp-cycle: If empty bmkp-nav-alist ask before setting it to bookmark-alist.
+;; 2017/02/26 dadams
+;;     Added:
+;;       bmkp-eww-rename-buffer, bmkp-eww-new-buffer-name, bmkp-eww-sans-pop-to-buffer,
+;;       bmkp-eww-buffer-handling (was ~bmkp-eww-allow-multiple-buffers-flag), 
+;;       bmkp-get-eww-mode-buffer, bmkp-eww-jumping-p, bmkp-eww-new-buf-name,
+;;       bmkp-jump-eww-in-buffer-*eww* (was ~bmkp-jump-eww-only-one-buffer),
+;;       bmkp-jump-eww-renaming-buffer (was ~bmkp-jump-eww-new-buffer), bmkp-info-auto-type,
+;;       bmkp-info-auto-bookmark-mode, bmkp-set-info-bookmark-with-node-name,
+;;       bmkp-toggle-info-auto-type.
+;;     Removed: bmkp-eww-allow-multiple-buffers-flag, bmkp-eww-set-new-buffer-name,
+;;              bmkp-jump-eww-new-buffer, bmkp-jump-eww-only-one-buffer.
+;;     bmkp-edit-bookmark-name-and-location: Don't consider changed-buffname-p if EWW bookmark.
+;;     bmkp-make-eww-record: Use bmkp-eww-new-buffer-name for buffer-name field.
+;;     Add bmkp-eww-rename-buffer to hooks eww-after-render-hook and eww-restore-history.
+;;     Support EWW only for Emacs 25+, not for 24.4+.  (E.g., bmkp-eww-title, bmkp-eww-url).
+;;     bookmark-show-all-annotations:
+;;       Use bookmark-maybe-load-default-file, to load bookmark file.
+;;       For Emacs 24+, call view-mode-enter with no args.  Thx to Alan Wehmann for bug report
+;;           and Martin Rudalics for info about the new signature.
+;;     bmkp-completing-read-1: Use single default, not list, for Emacs 20-22.
+;;     bmkp-default-bookmark-name:
+;;       Ensure use a single bname, not a list of names returned by bmkp-default-lighted.
+;; 2017/01/29 dadams
+;;     Added: bmkp-eww-title, bmkp-eww-url.
+;;     bookmark-set, bmkp-this-buffer-p, bmkp-make-eww-record: Use bmkp-eww-title, bmkp-eww-url.
+;; 2017/01/10 dadams
+;;     Added:
+;;       bmkp-eww-allow-multiple-buffers-flag, bmkp-eww-set-new-buffer-name, bmkp-jump-eww-new-buffer,
+;;       bmkp-jump-eww-only-one-buffer.
+;;     Renamed: bmkp-replace-eww-keys-flag     to bmkp-eww-replace-keys-flag,
+;;              bmkp-w3m-allow-multi-tabs-flag to bmkp-w3m-allow-multiple-buffers-flag,
+;;              bmkp-jump-w3m-new-session      to bmkp-jump-w3m-new-buffer,
+;;              bmkp-jump-w3m-only-one-tab     to bmkp-jump-w3m-only-one-buffer.  Keep old as aliases.
+;;     bmkp-jump-eww: Dispatch to bmkp-jump-eww-(new|only-one)-buffer
+;;     bmkp-jump-w3m-new-buffer, bmkp-jump-w3m-only-one-buffer: Use get-buffer-create, just in case.
+;;     bookmark-write-file:
+;;       Updated per latest fix for bug #25365: insert version stamp after writing bmks.  UNTESTED.
+;; 2017/01/08 dadams
+;;     Use the term "entry", not "property" everywhere, for bookmark entries (fields).
+;; 2017/01/07 dadams
+;;     bookmark-write-file, bookmark-load, bmkp-temporary-bookmarking-mode:
+;;       Use bookmark-file-coding-system (Emacs bug #25365).  UNTESTED.
+;; 2017/01/03 dadams
+;;     bookmark-location: Corrected doc string to reflect code: buffer before file.
+;; 2016/12/31 dadams
+;;     Added: bmkp-non-invokable-bookmark-p, bmkp-non-invokable-alist-only.
+;;     bmkp-bookmark-description: Include non-invokable.
+;; 2016/12/21 dadams
+;;     Added: bmkp-ffap-max-region-size, bmkp-ffap-guesser.
+;;     bmkp-file-target-set, bmkp-autofile-set, bmkp-autofile-(add|remove)-tags:
+;;       Use bmkp-ffap-guesser.bmkp-ffap-guesser, not ffap-guesser.
+;; 2016/12/11 dadams
+;;     Added: bmkp-convert-eww-bookmarks, bmkp-replace-eww-keys-flag.
+;; 2016/11/25 dadams
+;;     bmkp-make-function-bookmark: Added bookmark-make-record-default, to include creation date.
+;;     bmkp-make-sequence-record: Use 0 as position, in record.
+;;     bookmark-sort-flag: Replace doc string with mention that it is not used.
+;; 2016/11/23 dadams
+;;     bookmark-save, bookmark-write-file, bookmark-load, bmkp-empty-file, bmkp-tags-in-bookmark-file,
+;;       bmkp-list-defuns-in-commands-file, bmkp-set-bookmark-file-bookmark, bmkp-desktop-read:
+;;         Raise an error if we have a directory, not a file.
+;; 2016/11/18 dadams
+;;     Support Emacs 24.[45] too.
+;;     bookmark-set, bmkp-this-buffer-p, bmkp-make-eww-record: Update for Emacs 24.[45].
+;;     bmkp-edit-bookmark-name-and-location: Add support for EWW.
+;;     bmkp-jump-eww: Create buffer *eww* if it does not exist.
+;;     bmkp-crosshairs-highlight: Respect bmkp-crosshairs-highlight (not really needed).
+;;     bmkp-eww-cp: typos: w3m -> eww.
+;; 2016/11/15 dadams
+;;     bmkp-*eww-*, bookmark-set, bmkp-this-buffer-p, bmkp-url-bookmark-p, bmkp-url-target-set,
+;;       bmkp-bookmark-description: Ensure that EWW code is only for Emacs 25+.
+;; 2016/11/14 dadams
+;;     Added: bmkp-eww-jump, bmkp-eww-jump-other-window, bmkp-eww-alist-only, bmkp-eww-bookmark-p,
+;;            bmkp-eww-cp, bmkp-jump-eww, bmkp-make-eww-record, bmkp-eww-history.
+;;     bmkp-non-file-filename: Added EWW entry.
+;;     bookmark-set, bmkp-this-buffer-p, bmkp-url-bookmark-p, bmkp-url-target-set,
+;;       bmkp-bookmark-description: Support eww-mode.
+;;     bmkp-url-jump(-other-window): Just use bmkp-url-alist-only.
+;; 2016/10/27 dadams
+;;     bmkp-end-position-post-context: Typo: (point) -> ereg.
+;; 2016/09/21 dadams
+;;     Added: bmkp-desktop-default-directory.
+;;     Added: desktop-full-file-name, for Emacs < 22.
+;;     bmkp-set-desktop-bookmark, bmkp-desktop-change-dir, bmkp-desktop-read:
+;;       Use bmkp-desktop-default-directory when reading or expanding file name.
+;;     bmkp-desktop-change-dir: Error in interactive spec too, if cannot load desktop.el.
+;; 2016/09/10 dadams
+;;     Added: bmkp-format-spec.
+;;     bmkp-autoname-format: Use %B in default value.  Update doc string, allowing %B.
+;;     bmkp-autonamed-bookmark-p: Added optional arg BUFFER.  Use bmkp-format-spec.
+;;     bmkp-autonamed-bookmark-for-buffer-p, bmkp-autonamed-this-buffer-bookmark-p:
+;;       Use bmkp-autonamed-bookmark-p.
+;; 2016/09/06 dadams
+;;     Added: bmkp-read-from-whole-string.
+;;     bmkp-make-function-bookmark, bmkp-set-sequence-bookmark: Use bmkp-read-from-whole-string.
+;; 2016/06/23 dadams
+;;     bmkp-remove-all-tags, bmkp-add-tags, bmkp-set-tag-value, bmkp-remove-tags,
+;;       bmkp-paste-(add|paste)-tags, bmkp-autofile-add-tags:
+;;         Corrected doc string to say also that NO-UPDATE-P does not update mod count.
+;;     bookmark-store, bookmark-set, bookmark-relocate, bmkp-(url|file)-target-set,
+;;       bmkp-autofile-set, bmkp-autofile-remove-tags:
+;;         Renamed arg NO-UPDATE-P to NO-REFRESH-P.
+;; 2016/06/21 dadams
+;;     bmkp-edit-bookmark-records-send, bmkp-set-tag-value-for-bookmarks, bmkp-rename-tag,
+;;       bmkp-delete-bookmarks:
+;;         Put bookmark-save-flag let-binding around iteration only, so modification is recorded etc.
+;; 2016/05/30 dadams
+;;     bmkp-not-near-other-auto-idle-bmks: Corrected typo: test distance for POSITION, not point.
+;; 2016/04/23 dadams
+;;     Added: bmkp-set-dired-bookmark-for-files.
+;; 2015/10/31 dadams
+;;     bookmark-import-new-list: Added arg RETURN-BMKS: Return bookmarks added, if non-nil.
+;; 2015/09/07 dadams
+;;     bmkp-some: Return cons (ELEMENT . VALUE).
+;; 2015/08/16 dadams
+;;     Renamed bmkp-set-restrictions-bookmark to bmkp-set-izones-bookmark.
+;;     Renamed wide-n.el stuff to zones.el stuff.
+;; 2015/08/13 dadams
+;;     Removed: bmkp-readable-marker.
+;;     bmkp-set-restrictions-bookmark:
+;;       Added optional args.  A prefix arg prompts for VARIABLE.  Use wide-n-readable-marker.
+;; 2015/08/12 dadams
+;;     bmkp-set-restrictions-bookmark: Update for new wide-n format.
+;; 2015/08/10 dadams
+;;     bmkp-set-restrictions-bookmark:
+;;       Added missing comma, to eval end marker.  Corrected END: caddr now, not cddr.
+;; 2015/08/06 dadams
+;;     bmkp-some: Fixed yesterday's fix. ;-)
+;; 2015/08/05 dadams
+;;     bmkp-some: Fixed so it returns the first list element for which the predicate is true.
+;; 2015/07/31 dadams
+;;     bmkp-set-restrictions-bookmark: Use new wide-n-restrictions format: (NUM BEG END).
+;; 2015/06/26 dadams
+;;     Added: bmkp-function-alist-only.
+;; 2015/06/18 dadams
+;;     bmkp-bookmark-description: Print location, if present, for non-file bmk.  Thx Martin Oppegaard.
+;;     bookmark-location: Reordered - prefer buffer name to file name.
+;; 2015/06/17 dadams
+;;     bmkp-bookmark-description: Added another \t for URL:.
+;; 2015/06/15 dadams
+;;     Allow for POSITION in bookmarks to be nil or absent - updated bookmark-default-handler,
+;;       bmkp-region-bookmark-p, bmkp-handle-region-default, bmkp-goto-position, bmkp-jump-dired,
+;;       bmkp-not-near-other-auto-idle-bmks.
+;; 2015/05/23 dadams
+;;     bookmark-load: Reset bmenu stuff: bmkp-bmenu-marked-bookmarks, bmkp-modified-bookmarks,
+;;       bmkp-flagged-bookmarks, bmkp-bmenu-omitted-bookmarks, bmkp-bmenu-filter-function.
+;; 2015/04/24 dadams
+;;     bookmark-set: Clarified doc string wrt bookmarks that have the same name.
+;; 2015/04/13 dadams
+;;     bmkp-temporary-bookmarking-mode:
+;;       Have to do bookmark-insert-file-format-version-stamp here, because make-temp-file creates the
+;;       file, so it satisfies file-exists-p for bookmark-write-file.
+;; 2015/04/10 dadams
+;;     bmkp-remove-all-tags, bmkp-add-tags, bmkp-remove-tags:
+;;       Do not call bmkp-maybe-save-bookmarks if NO-UPDATE-P.
+;;     bmkp-set-tag-value-for-(navlist|bookmarks): Added optional arg MSG-P.
+;;     bmkp-set-tag-value-for-bookmarks:
+;;       Call bmkp-tags-list, bmkp-maybe-save-bookmarks, and bmkp-refresh/rebuild-menu-list.
+;;     bmkp-set-tag-value:
+;;       Pass non-nil NO-UPDATE-P to bmkp-add-tags.  Unless NO-UPDATE-P, call bmkp-tags-list,
+;;       bmkp-maybe-save-bookmarks, and bmkp-refresh/rebuild-menu-list.
+;;     bmkp-remove-tags-from-all: Call bmkp-maybe-save-bookmarks and bmkp-refresh/rebuild-menu-list.
+;;     bmkp-rename-tag, bmkp-purge-notags-autofiles: Call bmkp-maybe-save-bookmarks.
+;; 2015/03/23 dadams
+;;     bookmark-show-all-annotations: When in Bookmark List buffer, respect the sort order.
+;; 2015/02/24 dadams
+;;     bmkp-get-autofile-bookmark: Corrected 2015-02-15 fix - ensure BDIR is non-nil too, before test.
+;; 2015/02/22 dadams
+;;     Moved here from bookmark+-bmu.el:
+;;       bmkp-reset-bmkp-store-org-link-checking-p, bmkp-store-org-link-checking-p.
+;;       Advice of org-store-link (not needed for bmkp-bmenu-store-org-link).
+;;     bmkp-store-org-link(-1): Link type changed from bookmark-other-window to bookmark-other-win.
+;;     bookmark-prop-set: Added optional arg DONT-UPDATE-NAME.
+;;                        Update bmkp-full-record property on bookmark name, unless DONT-UPDATE-NAME.
+;;     bmkp-record-visit, bmkp-save-new-region-location, bmkp-goto-position:
+;;       Use arg DONT-UPDATE-NAME in sequence of calls to bookmark-prop-set.
+;; 2015/02/21 dadams
+;;     Added: bmkp-store-org-link, bmkp-store-org-link-1.
+;; 2015/02/15 dadams
+;;     bmkp-get-autofile-bookmark: Corrected test for same file to use absolute file names.
+;;     bmkp-read-bookmark-file-default: .emacs.bmk -> ~/.emacs.bmk.
+;; 2015/02/11 dadams
+;;     Added (redefinition of) bookmark-insert-current-bookmark for Emacs 24.3+.
+;; 2015/02/08 dadams
+;;     Added: bmkp-properties-to-keep, bmkp-tagged-alist-only, bmkp-untagged-alist-only.
+;;     Renamed: bmkp-icicle-* to bmkp-icicles-*.
+;;     bmkp-this-buffer-bmenu-list, bmkp-navlist-bmenu-list: Restore original values in case of error.
+;;     bookmark-set: Do not overwrite properties listed in option bmkp-properties-to-keep.
+;;     bmkp-prompt-for-tags-flag: Updated doc string wrt adding, not replacing.
+;;     bmkp-autofile-filecache: Corrected autoload cookie (typo).
+;; 2015/02/05 dadams
+;;     bookmark-insert-annotation: BOOKMARK can be a bookmark or its name.
+;; 2015/02/03 dadams
+;;     bmkp-occur-target-set: Removed unused let-binding.
+;; 2015/01/28 dadams
+;;     Added: bookmark-automatically-show-annotations, bmkp-show-this-annotation-read-only,
+;;            bmkp-edit-this-annotation.
+;;     Soft-require font-lock+.el.
+;;     bookmark-insert-annotation: Convert BOOKMARK input to its name.
+;;     bookmark-edit-annotation-mode: Bind key C-x C-q to bmkp-show-this-annotation-read-only.
+;;     bookmark-show-annotation-mode: Bind key C-x C-q to bmkp-edit-this-annotation.
+;;     bookmark-show-annotation:
+;;       If bookmark-automatically-show-annotations = edit then just call bookmark-edit-annotation.
+;;       Fix title highlighting (need font-lock+.el) and buffer-modified-p.
+;;       Set bookmark-annotation-name.  Use `, not ', in title.
+;;     bookmark-edit-annotation: Manage buffer-modified-p.
+;; 2015/01/17 dadams
+;;     Added bmkp-annotate-bookmark.
+;;     bookmark-show-annotation, bookmark-show-all-annotations: Made it interactive.
+;; 2015/01/01 dadams
+;;     bookmark-default-handler, bmkp-goto-position:
+;;       Do not bind enable-local-variables to nil - the visit is not hidden and temporary.
+;; 2014/12/18 dadams
+;;     bmkp-this-file-bmenu-list: Restore vars if error.
+;; 2014/12/16 dadams
+;;     bmkp-last-specific-file-p: Use bmkp-same-file-p, not string=.
+;; 2014/12/15 dadams
+;;     Added: bmkp-non-dir-file-jump, bmkp-non-dir-file-jump-other-window,
+;;            bmkp-local-non-dir-file-jump, bmkp-local-non-dir-file-jump-other-window,
+;;            bmkp-remote-non-dir-file-jump, bmkp-remote-non-dir-file-jump-other-window,
+;;            bmkp-non-dir-file-alist-only, bmkp-non-dir-file-bookmark-p,
+;;            bmkp-local-non-dir-file-alist-only, bmkp-local-non-dir-file-bookmark-p,
+;;            bmkp-remote-non-dir-file-alist-only, bmkp-remote-non-dir-file-bookmark-p.
+;;     bmkp-autotemp-bookmark-predicates: Added bmkp(-local|-remote)-non-dir-file-bookmark-p.
+;; 2014/11/15 dadams
+;;     Added: bmkp-region-jump-narrow-indirect-other-window, bmkp-handle-region+narrow-indirect.
+;;     bmkp-jump-man: Updated for Emacs 24+, where Man-getpage-in-background returns process buffer.
+;; 2014/11/14 dadams
+;;     bmkp-jump-1: Made arg FLIP-USE-REGION-P optional.  Corrected doc string for it: it flips.
+;;     bmkp-snippet-to-kill-ring, bmkp-autonamed-*jump*, bmkp-temporary-jump*, bmkp-w32-browser-jump,
+;;       bmkp-variable-list-jump, bmkp-autofile-jump*: Removed FLIP arg (optional).
+;;     bmkp-region-jump*: Bind bmkp-use-region to t, and don't pass FLIP arg to bmkp-jump-1.
+;; 2014/11/10 dadams
+;;     Added: bookmark-show-annotation-mode, (redefinition of) bookmark-default-annotation-text.
+;;     Renamed: bmkp-edit-annotation-mode-inherit-from to bmkp-annotation-modes-inherit-from.
+;;     bookmark-show-annotation: Call bookmark-show-annotation-mode, not view-mode-enter.
+;;     bookmark-edit-annotation-mode:
+;;       Use literal C-c C-M-c, since bookmark-send-edited-annotation is also bound to C-c C-c.
+;; 2014/11/09/dadams
+;;     Added: bmkp-get-external-annotation, bmkp-visit-external-annotation.
+;;     bookmark-show-annotation: If the annotation is external then jump to its destination.
+;; 2014/11/08 dadams
+;;     bmkp-bookmark-description: Corrected formatting for search-hits-p.
+;; 2014/10/28 dadams
+;;     Added: option bmkp-edit-annotation-mode-inherit-from.
+;;     bookmark-edit-annotation-mode: Redefined to use define-derived-mode (per Emacs 25).
+;;                                    Use new option bmkp-edit-annotation-mode-inherit-from.
+;;     bookmark-send-edited-annotation: Allow derived mode (per Emacs 25).
+;;     bookmark-edit-annotation:
+;;       Call bookmark-insert-annotation.  Set local var bookmark-annotation-name to arg (per E25).
+;; 2014/10/27 dadams
+;;     Added: Redefinition of bookmark-insert-annotation.
+;;     bookmark-edit-annotation-mode: Use bookmark-insert-annotation.
+;; 2014/08/22 dadams
+;;     bmkp-desktop-file-p: Redefined to not visit the file: use insert-file-contents-literally.
+;;                          Added (not (file-directory-p filename)) condition.
+;; 2014/08/21 dadams
+;;     Added: bmkp-annotated-bookmark-p.
+;;     bmkp-autofile-alist-only: Use bmkp-annotated-bookmark-p.
+;;     bmkp-completing-read-1: Bind icicle-bookmark-completing-p.
+;;     bmkp-file-this-dir-bookmark-p: Return nil if BOOKMARK is not a bookmark.
+;;                                    Use bmkp-same-file-p, not equal.
+;; 2014/08/19 dadams
+;;     Added: bmkp-dired-wildcards-alist-only, bmkp-navlist-bookmark-p.
+;; 2014/08/18 dadams
+;;     bmkp-this-file-p: Return nil (instead of raising error) if THIS-FILE is nil.
+;; 2014/07/11 dadams
+;;     bookmark-load: Do not customize-save-variable if no change to bmkp-last-as-first-bookmark-file.
+;;     bmkp-new-bookmark-default-names: Use setq, not push, for Emacs 20.
+;; 2014/07/06 dadams
+;;     Renamed: bmkp-show-end-of-region, bmkp-w3m-allow-multi-tabs to *-flag.
+;; 2014/07/05 dadams
+;;     bookmark-write-file: List in file could be (), in which case cannot search backward for \n).
+;;     bmkp-read-bookmark-for-type: Added optional PROMPT arg.
+;;     bmkp-jump-snippet: Provide PROMPT to bmkp-read-bookmark-for-type.  Better msg.
+;; 2014/07/03 dadams
+;;     Added: bmkp-read-bookmark-file-default.
+;;     Added redefinition of bookmark-import-new-list, bookmark-maybe-rename.
+;;     bookmark-load: Do not set blist to value of bookmark-import-new-list.
+;;     bookmark-alist-from-buffer: Added optional arg do-not-propertize-p.  (Not used anywhere yet.)
+;;     bookmark-save: Use bmkp-read-bookmark-file-default.
+;;     bookmark-write-file:
+;;       Added optional arg ADD.  Do not kill FILE buffer if it existed prior to invoking function.
+;;       Promoted inner let-bindings print-length etc.
+;;       Delete contents only if file does not exist (just in case). Else *-maybe-upgrade-file-format.
+;;       Do not delete region if ADD.  Position point depending on ADD.
+;;     bookmark-write-file, bookmark-default-handler, bmkp-save-menu-list-state, bmkp-goto-position,
+;;       bmkp-compilation-target-set:
+;;         Let-bind enable-local-variables around find-file-noselect.
+;;     bmkp-read-bookmark-file-name: Just pass DEFAULT-FILENAME to read-file-name.
+;;     bmkp-empty-file: Pass nil ADD arg to bookmark-write-file.
+;; 2014/06/29 dadams
+;;     Added: bmkp-before-jump-hook, bmkp-desktop-save, bmkp-desktop-save-as-last,
+;;            bmkp-desktop-current-file, bmkp-desktop-jump-save-before-flag.
+;;     bmkp-jump-1: Run bmkp-before-jump-hook.
+;;     bmkp-set-desktop-bookmark: Use bmkp-desktop-save.
+;;     bmkp-desktop-jump: If bmkp-desktop-jump-save-before-flag then bmkp-desktop-save-as-last.
+;;     bmkp-desktop-kill: Updated for Emacs 24.4+.
+;; 2014/06/21 dadams
+;;     Added: bmkp-icicle-search-hits-alist-only, bmkp-icicle-search-hits-bookmark-p,
+;;       bmkp-icicle-search-hits-retrieve-more, bmkp-jump-icicle-search-hits,
+;;       bmkp-retrieve-icicle-search-hits, bmkp-retrieve-more-icicle-search-hits,
+;;       bmkp-retrieve-icicle-search-hits-1, bmkp-set-icicle-search-hits-bookmark,
+;;       bmkp-make-icicle-search-hits-record, bmkp-unpropertized-string.
+;;     bmkp-bookmark-description: Handle Icicles search hits.
+;; 2014/05/30 dadams
+;;     bmkp-set-restrictions-bookmark: Updated for new restrictions format (wide-n.el).
+;; 2014/05/27 dadams
+;;     bmkp-describe-bookmark(-internals), bmkp-list-defuns-in-commands-file:
+;;       Use bmkp-with-help-window, not with-output-to-temp-buffer (Emacs 24.4+ silliness).
+;; 2014/04/05 dadams
+;;     Removed bmkp-create-dired-bookmarks-recursive: 
+;;      Moved to dired+.el and renamed diredp-do-bookmark-dirs-recursive.
+;; 2014/04/02 dadams
+;;     bmkp-paste-replace-tags: Added Note to doc string about pasting an empty list of tags.
+;; 2014/03/23 dadams
+;;     bmkp-file-target-set: Fix interactive spec (parens).
+;;     bmkp-file-target-set, bmkp-autofile-set, bmkp-autofile-(add|remove)-tags:
+;;       Soft-require ffap.el before using ffap-guesser.
+;; 2014/03/10 dadams
+;;     bookmark-write-file:
+;;       Remove prop face & Icicles props, anyway (but not bothering for sequence entry of seq bmks).
+;;     bookmark-write-file, bmkp-edit-tags, bmkp-save-menu-list-state, bmkp-readable-p:
+;;       Bind print-circle to bmkp-propertize-bookmark-names-flag, not t, to avoid string reuse.
+;; 2014/03/07 dadams
+;;     bookmark-exit-hook-internal: Do not raise error, since this is on kill-emacs-hook.
+;;     Bug reported: http://superuser.com/q/726057/250462.
+;; 2014/01/02 dadams
+;;     Reverted yesterday's change.  Just use cond instead of case.
+;; 2014/01/01 dadams
+;;     Added bmkp-file-cache-ad-hack, as workaround for macro case not getting byte-compiled.
+;;     file-cache-add-file: Use bmkp-file-cache-ad-hack.  Thx to Michael Heerdegen.
+;; 2013/11/21 dadams
+;;    bmkp-url-target-set: Added argument NO-OVERWRITE-P.
+;;    bmkp-(url|file)-target-set: Numeric prefix arg means do not overwrite.  N<0 means use full name.
+;; 2013/11/05 dadams
+;;     Added: bmkp-create-dired-bookmarks-recursive.
+;;     bookmark-set: Added optional arg NO-UPDATE-P - pass it to bookmark-store.
+;; 2013/10/29 dadams
+;;     Added: bmkp-pop-to-readable-marker, bmkp-readable-marker, bmkp-bookmark-set-confirm-overwrite,
+;;            bmkp-bookmark-set-confirms-overwrite-p.
+;;     bookmark-set: Ask for overwrite confirmation if plain prefix arg and bookmark exists.
+;;     bmkp-menu-bar-set-bookmark: Use bmkp-bookmark-set-confirm-overwrite, not bookmark-set.
+;; 2013/10/07 dadams
+;;     bmkp-edit-bookmark-records-send: Move to line of current bmk, if only one.
+;; 2013/08/09 dadams
+;;     Added: bmkp-read-bookmark-file-hook, bmkp-desktop-file-p.
+;;     Renamed: bmkp-printable-p to bmkp-readable-p.
+;;     bmkp-readable-p: Treat string with no text props separately.
+;;     bookmark-alist: Updated doc string.
+;;     bookmark-send-edited-annotation: looking-at -> bmkp-looking-at-p (new).
+;;     bookmark-load: Update blist with bookmark-import-new-list.
+;;                    Run bmkp-read-bookmark-file-hook after reading the bookmark file.
+;;     bmkp-set-desktop-bookmark: Added prefix arg: sets bookmark without saving desktop file.
+;; 2013/07/24 dadams
+;;     bmkp-new-bookmark-default-names, bookmark-make-record-default:
+;;       Test using (region-beginning|end), not mark function (C code and simpler).
+;; 2013/07/11 dadams
+;;     bmkp-url-target-set: Use let* with backquote lambda instead of lexical-let*.
+;; 2013/07/02 dadams
+;;     bmkp-snippet-bookmark-p: Typo: bmkp-snippet-to-kill-ring -> bmkp-jump-snippet.
+;;     bmkp-bookmark-description: Include snippet text in bookmark description (help).
+;; 2013/07/01 dadams
+;;     bookmark-make-record-default: Fixed typo for end-position (listify).
+;;     bmkp-set-snippet-bookmark: Prefix arg now prompts for bookmark name.
+;; 2013/06/30 dadams
+;;     Added: bmkp-set-snippet-bookmark, bmkp-snippet-to-kill-ring, bmkp-jump-snippet,
+;;            bmkp-snippet-alist-only, bmkp-snippet-bookmark-p, bmkp-snippet-history.
+;;     bmkp-autotemp-bookmark-predicates, bmkp-types-alist, bmkp-bookmark-type,
+;;       bmkp-bookmark-description:
+;;         Cover snippet bookmarks too.
+;;     bookmark-make-record-default:
+;;       Added optional arg NO-REGION.  If non-nil then do not include end-position.
+;;       Set NO-CONTEXT to nil for Emacs < 24.  Do not calculate FCS, RCS, FCRS, ECRS if NO-CONTEXT.
+;;     bmkp-make-(gnus|sequence|desktop|bookmark-file|variable-list)-record:
+;;       Pass NO-REGION to bookmark-make-record-default.
+;; 2013/06/29 dadams
+;;     Added: bmkp-read-regexp, bmkp-find-tag-default-as-regexp.
+;;     Use bmkp-read-regexp, not read-string, everywhere for reading a regexp.
+;;     bmkp-bookmark-description: Ensure FILE is non-nil before using it.
+;; 2013/06/10 dadams
+;;     bmkp-set-sequence-bookmark: Typo - bookmark-get-bookmarkp -> bookmark-get-bookmark.
+;; 2013/06/02 dadams
+;;     bmkp-set-sequence-bookmark: Forgot to bind FUN.  Thx to Michael Heerdegen.
+;; 2013/05/31 dadams
+;;     bmkp-save-menu-list-state: Display warning, do not raise error, if write-file fails.
+;;     bookmark-write-file: Use display-warning, if fboundp.
+;; 2013/05/28 dadams
+;;     Renamed: bmkp-edit-bookmark-name-and-file to bmkp-edit-bookmark-name-and-location.
+;;     bmkp-edit-bookmark-name-and-location: Handle location property, urls.
+;;     bmkp-jump-w3m-new-session, bmkp-jump-w3m-only-one-tab: Use location property, not filename.
+;;     Thx to Michael Heerdegen.
+;; 2013/05/15 dadams
+;;     bmkp-*-alist-only: Make sure we call bookmark-maybe-load-default-file.
+;;     Moved bmkp-string-match-p to bookmark+-bmu.el.
+;;     Use bmkp-string-match-p instead of string-match wherever appropriate.
+;; 2013/05/12 dadams
+;;     Added: bmkp-write-bookmark-file-hook.
+;;     bookmark-write-file: Run bmkp-bookmark-write-file-hook functions after writing.
+;; 2013/04/19 dadams
+;;     bookmark-exit-hook-internal: Removed test for non-empty bookmark-alist (Emacs bug #13972).
+;; 2013/04/15 dadams
+;;     bmkp-set-sequence-bookmark: Corrected case of adding one sequence to another.
+;;     bookmark-write-file: Corrected write-out of sequence bookmarks.
+;;     bookmark-alist-from-buffer: Better error message if read error.
+;; 2013/04/14 dadams
+;;     Added: bmkp-wrap-bookmark-with-last-kbd-macro, bmkp-dired-remember-*-marks.
+;;     bookmark-write-file: If not saving propertized, remove text props for bmks in sequence bmk.
+;;     bmkp-edit-bookmark-record-send:
+;;       Raise error if bmkp-edit-bookmark-record-send was somehow reset to nil.
+;;       Do not reset bmkp-edit-bookmark-orig-record if read error.
+;;     bmkp-make-function-bookmark:
+;;       Prefix arg means use last-kbd-macro instead of prompting for FUNCTION.
+;;       Use read-from-whole-string, not read, to convert name to symbol.
+;;       If FUNCTION is a function or vector, do not convert it.
+;;     bmkp-bookmark-description: For sequence-p, remove properties from each bmk name in sequence.
+;;     Define bmkp-bookmark-name-from-record (no longer a defalias) with an optional UNPROPERTIZE arg.
+;;     bmkp-make-dired-record: Use bmkp-dired-remember-*-marks, not dired-remember-marks.
+;;       FUNCTION can now be a vector (a keyboard macro).  Use read-from-whole-string, not read.
+;;     bmkp-jump-function: If function property is a vector, invoke it as a keyboard macro.
+;;     bmkp-set-sequence-bookmark:
+;;       Prefix ARG now allows for replace, in addition to append and prepend.  No replace question.
+;;       A BOOKMARK-NAMES item can now be a bookmark, a function, or keyboard macro - or its name.
+;;       A BOOKMARK-NAMES item that is itself a sequence has its bookmarks spliced in.
+;;       Use lax as value of NAMES-ONLY-P to bmkp-completing-read-bookmarks.
+;; 2013/04/12 dadams
+;;     Added: bmkp-sequence-alist-only.
+;;     bmkp-set-sequence-bookmark: Added prefix arg PREPENDP.  Use bmkp-completing-read-lax.
+;;     Use \\<bmkp-edit-bookmark-record-mode-map> in doc strings with *-record-send.
+;;     bookmark-get-bookmark: A cons must also have a string car, to tell a bmk from a list of bmks.
+;;     bmkp-make-function-bookmark: Use bmkp-completing-read-lax for BOOKMARK-NAME.
+;; 2013/04/10 dadams
+;;     Added: bmkp-set-sequence-bookmark, bmkp-make-sequence-record, bmkp-completing-read-bookmarks.
+;;     bmkp-completing-read-1:
+;;       Do not put DEFAULT in PROMPT if DEFAULT is "".  Removed useless let-binding of DEFAULT.
+;;       Removed unnecessary final massaging of STR.
+;;     bookmark-completing-read: Mention in doc string that nil DEFAULT means return "".
+;; 2013/03/29 dadams
+;;     bmkp-toggle-saving-bookmark-file: If neither is nil, set *-last-* to nil before toggling.
+;; 2013/03/17 dadams
+;;     bmkp-bmenu-list-1: Do not toggle filenames unless bookmark-alist is defined (Emacs bug #13972).
+;; 2013/01/07 dadams
+;;     bmkp-remove-all-tags, bmkp(-autofile)-(add|remove)-tags, bmkp-set-tag-value,
+;;       bmkp-paste-(add|replace)-tags, bmkp-(url|file)-target-set, bmkp-autofile-set:
+;;         Added missing NO-UPDATE-P arg for interactive spec.
+;;     bmkp-remove-all-tags: Moveed msg to the end.
+;;     bmkp-paste-replace-tags: Added sleep-for after first msg.
+;; 2012/11/13 dadams
+;;     bmkp-sorting-description: Fixed 1st case: use ORDER only if bmkp-sort-comparer is also non-nil.
+;; 2012/11/11 dadams
+;;     Added: bmkp-sorting-description (factored out from bmkp-msg-about-sort-order).
+;;     bmkp-msg-about-sort-order: Use bmkp-sorting-description.
+;;     bmkp-current-sort-order: Return nil if bmkp-sort-comparer is not in bmkp-sort-orders-alist.
+;; 2012/11/09 dadams
+;;     Added: bmkp-autofile-filecache.
+;;     Added defadvice for file-cache-add-file.
+;;     bookmark-store, bmkp-url-target-set: Added optional arg NO-UPDATE-P.
+;;     bookmark-set, bmkp-make-function-bookmark, bmkp-url-target-set, bmkp-file-target-set:
+;;       Adjusted calls to bookmark-store to accommodate NO-UPDATE-P arg.
+;;     bmkp-make-record-for-target-file:
+;;       Add CREATED property for all bookmark types.  Factor out the common stuff.
+;;       Remove any text properties from FILE arg before using it.
+;; 2012/10/09 dadams
+;;     Made all autoload cookies explicitly load bookmark+.el(c).  Should help ELPA (e.g. MELPA).
+;; 2012/10/01 dadams
+;;     bmkp-thing-at-point: Updated per icicle-thing-at-point.  Thx to Joe Bloggs.
+;; 2012/09/29 dadams
+;;     Added redefinition of bookmark-version-control.
+;;     bookmark--jump-via:
+;;       When bmkp-use-w32-browser-p, just handle, do after-jump hook & jump-fn, and show annotation.
+;;     bookmark-handle-bookmark:
+;;       When bmkp-use-w32-browser-p, just invoke w32-browser and throw to bookmark--jump-via.
+;;     bookmark-write-file: Use find-file-noselect.
+;;     bmkp-save-menu-list-state:
+;;       Bind print-circle, version-control, require-final-new-line.  Use find-file-noselect.
+;;       Copy shared bookmark lists and single strings, to avoid circular refs.
+;;       Raise error, not just msg, if file-error.
+;;     bookmark-write-file: Bind require-final-newline.
+;; 2012/09/26 dadams
+;;     bmkp-save-menu-list-state: Use write-file, not write-region, so backups are made.
+;; 2012/09/24 dadams
+;;     bookmark-write-file: Use write-file, not write-region, so backups are made.  Emacs bug #12507.
+;; 2012/09/22 dadams
+;;     bookmark-set: Updated handling of bmkp-auto-light-when-set for (non-)autonamed-in-buffer.
+;;     bmkp-autonamed-this-buffer-bookmark-p: Require that the buffer name part match also.
+;;     bmkp-autonamed-this-buffer-alist-only: Corrected to use bmkp-autonamed-this-buffer-bookmark-p.
+;; 2012/09/11 dadams
+;;     bmkp-set-autonamed-bookmark-at-line: Use prefix arg for line no.  Use line-beginning-position.
+;; 2012/09/06 dadams
+;;     Added: bmkp-string-match-p.
+;; 2012/08/28 dadams
+;;     bookmark-send-edited-annotation: Record an empty annotation as nil, not "".
+;; 2012/08/21 dadams
+;;     Call tap-put-thing-at-point-props after load thingatpt+.el.
+;; 2012/08/18 dadams
+;;     Invoke tap-define-aliases-wo-prefix if thingatpt+.el is loaded.
+;;     Added: bmkp-thing-at-point.
+;;     thing-at-point -> bmkp-thing-at-point, everywhere.
+;; 2012/08/10 dadams
+;;     Info-bookmark-make-record: Updated wrt Emacs 24.
+;;     Renamed: old-bookmark-insert to bmkp-ORIG-bookmark-insert.
+;; 2012/07/04 dadams
+;;     bmkp-create-variable-list-bookmark: Removed INTERACTIVEP arg to bookmark-set.
+;;     #'(lambda...) -> (lambda...).
+;; 2012/07/02 dadams
+;;     bmkp-default-handler-for-file:
+;;       Reverted 2012/05/04 change to use lexical-let.  Byte code in saved bookmark was problematic.
+;; 2012/06/26 dadams
+;;     Wrapped require of bookmark+-mac.el in eval-when-compile.
+;; 2012/06/21 dadams
+;;     Try to load-library bookmark+-mac.  Require it only if cannot load-library.
+;; 2012/06/12 dadams
+;;     bmkp-new-bookmark-default-names: 1. Test for DEFS at end is listp, not consp. 2. Return FNS.
+;;     bmkp-completing-read-1: Removed empty-input loop - caller must provide a default or handle "".
+;; 2012/06/1 dadams
+;;     bookmark-make-record: Replace an empty bookmark name with <EMPTY NAME>.
+;;     bookmark-set, bmkp-completing-read-1: Require user to input a non-empty bookmark name.
+;;     bmkp-bookmark-name-member: If NAME is null, just use member.  Skip any in NAMES that is null.
+;; 2012/05/16 dadams
+;;     Added: bmkp-string-less-case-fold-p.
+;;     bmkp-list-all-tags: List tags alphabetically.  Thx to Anders Johansson for the suggestion.
+;; 2012/05/05 dadams
+;;     bookmark-store, bmkp-make-function-bookmark, bmkp-unomit-all, bmkp-url-target-set:
+;;       Added optional arg NO-MSG-P.
+;;     bookmark-store, bookmark-set, bmkp-record-visit, bmkp-make-function-bookmark,
+;;       bmkp-current-bookmark-list-state, bmkp-unomit-all, bmkp-url-target-set, bmkp-file-target-set,
+;;       bmkp-replace-existing-bookmark:
+;;         Pass NO-MSG-P to *-refresh/rebuild-menu-list, *-surreptitiously-rebuild-list, *-store.
+;; 2012/05/04 dadams
+;;     bmkp-remove-tags, bmkp-all-tags(-regexp)-alist-only
+;;       bmkp(-(auto)file(-this-dir))(-(all|some)-tags)(-regexp)-alist-only,
+;;       bmkp-specific-(buffers|files)-alist-only, bmkp-sort-omit, bmkp-url-target-set,
+;;       bmkp-autofile-remove-tags. bmkp-default-handler-for-file, bmkp-set-bookmark-file-bookmark,
+;;       bmkp-set-desktop-bookmark, bmkp-set-variable-list-bookmark,
+;;       bmkp-create-variable-list-bookmark, bmkp-jump-dired,
+;;       bmkp-find-file-(all|some)-tags(-regexp)(-other-window):
+;;         Use lexical-let(*), to get closures for free vars in lambdas.
+;;     bmkp-regexp-filtered-(file-name|tags)-alist-only: Moved let inside lambda.
+;;     bmkp-make-dired-record: Use car instead of (lambda (x) (car x)).
+;; 2012/05/01 dadams
+;;     Added: bmkp-tagged-bookmark-p (alias), bmkp-tagged-cp.
+;;     bmkp-(add|remove)-tags: Return negative nb-* if changed from (un)tagged to not (un)tagged.
+;;     bmkp-paste-replace-tags: Do not call bmkp-remove-all-tags unless there are tags to remove.
+;; 2012/04/27 dadams
+;;     bmkp-edit-(tags|bookmark-record): Use bmkp-with-output-to-plain-temp-buffer.
+;; 2012/04/18 dadams
+;;     Do not try to define bmkp-global-auto-idle-bookmark-mode for Emacs 21 (no define-globalized*).
+;; 2012/04/16 dadams
+;;     bmkp-bookmark-description: List tags as strings on separate lines.
+;;                                Add newline after annotation.
+;; 2012/04/13 dadams
+;;     Added: bmkp-(flagged|modified)-bookmark-p, bmkp-(flagged|modified)-cp.
+;;     bookmark-store, bookmark-set-name, bookmark-prop-set, bmkp-edit-bookmark-record(s)-send,
+;;       bmkp-replace-existing-bookmark, bmkp-delete-bookmarks:
+;;         Use (equivalent of) eq version of add-to-list.
+;; 2012/04/10 dadams
+;;     Added: bmkp-count-multi-mods-as-one-flag.
+;;     bmkp-edit-bookmark-records-send, bmkp-set-tag-value-for-bookmarks, bmkp-remove-tags-from-all,
+;;       bmkp-rename-tag, bmkp-purge-notags-autofiles,
+;;       bmkp-delete(-all)-autonamed(-for)(-this-buffer)(-no-confirm), bmkp-delete-bookmarks,
+;;       bmkp-delete(-all)-temporary(-bookmarks|-no-confirm):
+;;         Corrected bookmark-save to bookmark-save-flag in bindings to nil.
+;;         Use bmkp-count-multi-mods-as-one-flag for the binding.
+;; 2012/04/09 dadams
+;;     bookmark-relocate, bmkp-edit-bookmark-records-send, bmkp-set-tag-value, bmkp-file-target-set,
+;;       bmkp-autofile-set:
+;;         Added optional arg NO-UPDATE-P.  Use it to inhibit display refreshing.
+;;     bmkp-edit-bookmark-records-send, bmkp-set-tag-value-for-bookmarks, bmkp-remove-tags-from-all,
+;;       bmkp-rename-tag, bmkp-purge-notags-autofiles, delete-all-autonamed-for-this-buffer
+;;       bmkp-delete(-all)-temporary-(bookmarks|no-confirm), bmkp-delete-bookmarks,
+;;       bmkp-delete-autonamed(-this-buffer)(-no-confirm):
+;;         Bind bookmark-save to nil around iteration, to inhibit saving until finished.
+;;     bmkp-(add|remove)(-all)-tags, bmkp-paste-(add|replace)-tags, bmkp-autofile-(add|remove)-tags:
+;;       Swapped order of args MSGP and NO-UPDATE-P (put MSGP last).
+;;     bmkp-(add|remove)(-all)-tags, bmkp-autofile-(add|remove)-tags:
+;;       Use NO-UPDATE-P also to inhibit display refreshing.
+;;     bmkp-remove-tags-from-all: Pass non-nil NO-UPDATE-P arg to bmkp-remove-tags.
+;; 2012/04/07 dadams
+;;     Added: bmkp-new-bookmark-default-names (option & function).
+;;     Redefine bookmark-make-record (for all Emacs versions) to use bmkp-new-bookmark-default-names.
+;;     bookmark-set: Use bmkp-new-bookmark-default-names (multiple defaults).
+;;                   Moved the region-text default value stuff to fn bmkp-new-bookmark-default-names.
+;;     bmkp-completing-read-1: Handle a cons DEFAULT.
+;;     Added soft require of thingatpt+.el.
+;; 2012/04/06 dadams
+;;     Added: bmkp-auto-idle-bookmark-min-distance, bmkp-not-near-other-auto-idle-bmks,
+;;            bmkp-auto-idle-bookmarks.
+;;     bmkp-autotemp-bookmark-predicates:
+;;       Changed default value to include bmkp-autonamed-bookmark(-this-buffer)-p.
+;;     bookmark-store: Add the bookmark to bmkp-auto-idle-bookmarks (if appropriate).
+;;     bookmark-delete: Remove the bookmark from bmkp-auto-idle-bookmarks.
+;;     bmkp-auto-idle-bookmark-mode:
+;;       Bind bmkp-setting-auto-idle-bmk-p.  Do nothing if bmkp-not-near-other-auto-idle-bmks says so.
+;; 2012/04/05 dadams
+;;     Added (Emacs 21+): bmkp-global-auto-idle-bookmark-mode, bmkp-turn-on-auto-idle-bookmark-mode.
+;;     bmkp-auto-idle-bookmark-mode (Emacs 21+):
+;;       Made it local:
+;;         Removed keyword :global, added keyword :require.
+;;         Timer function does nothing if the mode is not enabled (i.e., for the current buffer).
+;;     bmkp-auto-idle-bookmark-mode (Emacs 20):
+;;       Changed interactive spec to handle toggle symbol.
+;;       Timer function does nothing if the mode is not enabled (for the current buffer, if local).
+;;       Change message to mention buffer when the mode is local.
+;;     Removed: bmkp-auto-idle-bookmark-mode-hook.
+;;     Added autoload cookie for Emacs 20 defcustom for bmkp-auto-idle-bookmark-mode.
+;;     bmkp-auto-idle-bookmark-mode-timer: Use nil as default value.
+;;     bmkp-auto-idle-bookmark-mode: If timer is non-nil, set it to nil (and cancel it).
+;; 2012/04/04 dadams
+;;     Added: bmkp-auto-idle-bookmark-mode(-delay|-hook|-lighter|-set-function),
+;;            bmkp-temporary-bookmarking-mode-lighter, bmkp-auto-idle-bookmark-mode-timer.
+;;     bmkp-temporary-bookmarking-mode: Added lighter.
+;;     bookmark-set: Pass INTERACTIVEP arg, not constant MSGP, to bmkp-light-(bookmarks|this-buffer).
+;; 2012/04/03 dadams
+;;     Moved to bookmark+-bmu.el: bmkp-face-prop.
+;; 2012/04/02 dadams
+;;     bmkp-toggle-autonamed-bookmark-set/delete, bmkp-set-autonamed-bookmark(-at-line),
+;;       bmkp-delete-bookmarks:
+;;         Made POSITION, NUMBER, ALLP optional.
+;; 2012/03/18 dadams
+;;     Added: bmkp-modified-bookmarks, redefinition of bookmark-set-name.
+;;     bookmark-store, bookmark-set-name, bookmark-prop-set, bmkp-replace-existing-bookmark:
+;;       Add the bookmark to bmkp-modified-bookmarks.
+;;     bookmark-rename: Call bmkp-rename-for-marked-and-omitted-lists _after_ set new name w/ prop.
+;;     bookmark-save: Reset bmkp-modified-bookmarks.  Call bmkp-refresh/rebuild-menu-list.
+;;     bmkp-rename-for-marked-and-omitted-lists: Fixed typo: marked -> omitted.
+;;     bmkp-edit-bookmark-name-and-file:
+;;       Save each of bmk name and file name only if changed (bug fix).  Provide default file name.
+;;       If no automatic save, and modifications, ask user whether to save.
+;;     bmkp-edit-bookmark-records-send:
+;;       Add updated bookmarks to bmkp-modified-bookmarks.
+;;       Merge sanity-check dolist with main dolist.
+;;       Set bmkp-bmenu-marked-bookmarks to names in bmkp-modified-bookmarks, not in edited-bookmarks.
+;;     bmkp-edit-bookmark-record: Use (shallow) copy of bmkp-edit-bookmark-orig-record, not original.
+;;     bmkp-edit-bookmark-record-send: Add updated bookmark to bmkp-modified-bookmarks.
+;;     bmkp-record-visit: Let-bind bmkp-modified-bookmarks to itself, so will be restored.
+;;     bmkp-refresh-menu-list: Pass no FILTEREDP if no current filter (start anew).
+;;     bmkp-bookmark-name-member: If a name in NAMES is unpropertized, don't try to match property.
+;;     bmkp-replace-existing-bookmark: For propertize bookmark-current-bookmark with bmkp-full-record.
+;; 2012/03/13 dadams
+;;     bmkp-incremental-filter-delay:
+;;       Use bookmark-search-delay as default value, if available.  Else use 0.2 (not 0.6).
+;; 2012/03/11 dadams
+;;     bmkp-revert-bookmark-file: Added p to interactive spec (forgot).
+;; 2012/03/06 dadams
+;;     Added: bmkp-revert-bookmark-file.
+;;     bookmark-load: If bookmark-file buffer already existed, do not kill it after loading.
+;; 2012/03/04 dadams
+;;     Added: bmkp-refresh/rebuild-menu-list.
+;;     bookmark-store, bookmark-send-edited-annotation, bookmark-delete,
+;;       bmkp-edit-bookmark-record(s)-send, bmkp-edit-tags-send, bmkp-update-autonamed-bookmark,
+;;       bmkp-remove(-all)-tags, bmkp-add-tags, bmkp-file-target-set, bmkp-refresh/rebuild-menu-list:
+;;         Use bmkp-refresh/rebuild-menu-list.
+;;     bookmark-load:
+;;       Use bmkp-refresh/rebuild-menu-list only if interactive.  Do not call *-surreptitiously-*.
+;;     bmkp-edit-bookmark-record(s)-send: Added optional arg MSGP.  Raise read error if batch.
+;;     bmkp-record-visit:
+;;       Added optional arg BATCHP.  Do not bookmark-bmenu-surreptitiously-rebuild-list if BATCHP.
+;;     bmkp-edit-tags-send: Added optional arg BATCHP, and pass it to bmkp-record-visit.
+;;     bmkp-refresh-menu-list: Use bmkp-bookmark-name-from-record only when BOOKMARK is non-nil.
+;;     bmkp-paste-replace-tags, bmkp-(compilation|occur)-target-set-all:
+;;       Raise error with OK message if user cancels.
+;;     bmkp-purge-notags-autofiles, bmkp-delete-all-temporary-bookmarks: Added optional arg MSGP.
+;;     bmkp-purge-notags-autofiles, bmkp-delete-all-temporary-bookmarks,
+;;       bmkp-delete-temporary-no-confirm:
+;;         Call bmkp-refresh/rebuild-menu-list after the dolist.  Inhibit refresh for bookmark-delete.
+;;     bmkp-jump-bookmark-file: Removed reference to current-prefix-arg: prompt only if SWITCHP.
+;;     bmkp-delete-all-autonamed-for-this-buffer:
+;;       Added optional arg MSGP.  Prompt for confirmation only if MSGP.
+;;     bmkp-delete-autonamed-this-buffer-no-confirm:
+;;       Added optional arg NO-REFRESH-P.  Inhibit refresh for bookmark-delete.
+;;       Unless  NO-REFRESH-P, call bmkp-refresh/rebuild-menu-list after the dolist.
+;;     bmkp-delete-autonamed-no-confirm:
+;;       Call bmkp-delete-autonamed-this-buffer-no-confirm with NO-REFRESH-P.
+;;       Call bmkp-refresh/rebuild-menu-list after the dolist.
+;;     bmkp-delete-bookmarks:
+;;       Added optional arg MSGP.  Prompt for confirmation only if MSGP.
+;;       Raise error with OK message if user cancels.
+;;       Call bmkp-refresh/rebuild-menu-list after the dolist.  Inhibit refresh for bookmark-delete.
+;;       Use bmkp-this-buffer-alist-only, not bookmark-alist, for selecting bookmarks.
+;;       Use `...', etc. when echoing deleted bookmarks.
+;; 2012/03/02 dadams
+;;     bookmark-load:
+;;       Changed last arg from NO-MSG-P to BATCHP.  If non-nil, act with no prompt, saving or not.
+;;       If nil, prompt user whether to save before loading.  If user quits with C-g, do not load.
+;;     bookmark-maybe-load-default-file: Pass symbol nosave, not t, as last arg to bookmark-load.
+;;     bmkp-switch-bookmark-file-create: Last arg is now the complement: BATCHP, not INTERACTIVEP.
+;;     bmkp-temporary-bookmarking-mode: Pass nosave as last arg to bookmark-load, since do save here.
+;;     bmkp-default-handlers-for-file-types: Added eval-when-compile to require cl.el for Emacs 20.
+;;     bmkp-maybe-save-bookmarks: Added optional arg SAME-COUNT-P.
+;;     bmkp-record-visit: Pass non-nil arg to bmkp-maybe-save-bookmarks to prevent changing mod count.
+;;     bookmark-store: Call bmkp-refresh-menu-list if Bookmark List is displayed.
+;;     bmkp-toggle-saving-bookmark-file: Added optional arg MSGP - show message only if non-nil.
+;;     bmkp-find-file(-other-window): Added missing FIL arg for error format string.
+;;     bmkp-temporary-bookmarking-mode: Pass a MSGP arg to bmkp-toggle-saving-bookmark-file.
+;; 2012/02/29 dadams
+;;     bmkp-completing-read-lax: Bind & restore C-M-w, C-M-u, SPC, and ? (so can insert SPC, ? etc.).
+;; 2012/02/28 dadams
+;;     bmkp-file-target-set: Call bmkp-refresh-menu-list if Bookmark List is displayed.
+;;     Renamed option bmkp-default-handler-associations to bmkp-default-handlers-for-file-types.
+;;       bmkp-default-handler-associations is NOW OBSOLETE - RENAME IT IF YOU HAVE CUSTOMIZED IT.
+;;     bmkp-same-file-p: Take advantage of Emacs 24 function, file-equal-p.  Thx to Michael Albinus.
+;;     bmkp-find-file(-other-window):
+;;       Added optional args CREATE-AUTOFILE-P & MSGP (new arg order).  Prefix arg creates bookmark.
+;;       Use bmkp-default-handlers-for-file-types even for files not bookmarked.
+;; 2012/02/26 dadams
+;;     Added: bmkp-(autofile|autonamed)-history, bmkp-autofile-(all|some)-tags(-regexp)-alist-only,
+;;            bmkp-autofile(-(all|some)-tags(-regexp))-jump(-other-window).
+;;     bmkp-types-alist: Added entries for (autofile|autonamed).
+;;     Everywhere that read-file-name is used:
+;;       Bind icicle-unpropertize-completion-result-flag to t, for read-file-name.
+;;     No longer alias bmkp-autofile*-jump to bmkp-find-file.  The *-autofile-*jump commands use
+;;       bmkp-read-bookmark-for-type and bmkp-jump-1, not read-file-name and find-file.
+;;     bmkp-find-file(-other-window):
+;;       Added optional args FILE MUST-EXIST-P.
+;;       Use read-file-name and either bookmark-jump or find-file, not just find-file (and no PRED).
+;;     bmkp-find-file-*-tags(-regexp)(-other-window):
+;;       Added optional FILE arg.
+;;       Use bookmark-jump, not find-file - so only autofiles with the tags are candidates.
+;;       Bind icicle-must-pass-after-match-predicate.  Use PRED for read-file-name only if no Icicles.
+;;     The new bmkp-find-file* commands are bound to ... C-f, not ... a.
+;;     bmkp-default-handler-associations: Correct docstring: double backslashes.
+;; 2012/02/21 dadams
+;;     bmkp-jump-to-type(-other-window): Corrected ALIST: If no HISTORY do not call *-alist-only.
+;; 2012/02/20 dadams
+;;     bookmark-handle-bookmark: Handle, in priority, new property file-handler.
+;;     bookmark-default-handler: Handle new property file-handler.
+;;     bmkp-make-record-for-target-file:
+;;       Use new property file-handler, not handler, for default handler.
+;;       Use file-handler with play-sound-file, not handler with bmkp-sound-jump (deprecated).
+;;     bmkp-default-handler-for-file: Return function bmkp-user, not a lambda that applies it to file.
+;;     bmkp-handler-pred:
+;;       Return t if TYPE is handler or file-handler.  Do not match a lambda that applies the handler.
+;;     bmkp-default-handler-associations, bookmark-alist, bmkp-jump-to-type:
+;;       Updated doc string to reflect new implementation of file handlers using prop file-handler.
+;; 2012/02/19 dadams
+;;     Added: bmkp-handler-pred, bmkp-temporary-history, bmkp-w32-browser-jump.
+;;     bmkp-types-alist: Added bmkp-temporary-history.
+;;     bmkp-read-bookmark-for-type: Prepend a space before "bookmark" in prompt.
+;;     bmkp-jump-to-type:
+;;       Use lax completion.
+;;       When call bmkp-read-bookmark-for-type:
+;;        Do not append a space to TYPE name passed.
+;;        Pass a predicate arg returned by bmkp-handler-pred when TYPE is not a known type.
+;;     bmkp-*-jump(-other-window): Remove space after TYPE name passed to bmkp-read-bookmark-for-type.
+;;     bmkp-(specific-(buffers|files)|temporary)-jump(-other-window):
+;;       Pass specific HIST arg to bmkp-read-bookmark-for-type.
+;; 2012/02/16 dadams
+;;     Updated for Emacs 24+:
+;;       bookmark-set: Do not set bookmark-(yank-point|current-buffer) if set.
+;;       bmkp-make-gnus-record: Be able to bookmark from article buffer, as well as summary buffer.
+;;       bmkp-jump-gnus: Go to article buffer if location field says to.
+;;     Use bmkp-make-gnus-record (not gnus-summary-bookmark-make-record) for Emacs 24+ also.
+;; 2012/02/14 dadams
+;;     bmkp-set-desktop-bookmark: Provide default for read-file-name.  Thx to Markus Grunwald.
+;;                                Provide all bookmarked desktop files as Icicles proxy candidates.
+;; 2012/02/08 dadams
+;;     bmkp-autofile-set: Use MSGP also for the case where the bookmark already exists.
+;;     bmkp-remove-dups: Redefined to use a hash table.
+;; 2012/02/07 dadams
+;;     bmkp-same-file-p: Test compare-strings result using t, not non-nil.  Thx to Michael Heerdegen.
+;; 2012/02/04 dadams
+;;     Added: bmkp-tags-for-completion, bmkp-tags-in-bookmark-file.
+;;     Use bmkp-tags-for-completion for tags completing everywhere - updated doc strings.
+;;     bmkp-list-all-tags: Added args current-only-p and (optional) msgp.
+;;                         Different prefix arg values for different behaviors.
+;;     bmkp-tags-list: Added optional arg current-only-p.  Use bmkp-tags-for-completion by default.
+;; 2012/01/20 dadams
+;;     bmkp(-autofile)-(add|remove)-tags(-from-all), bmkp-find-file-(all|some)-tags(-other-window),
+;;       bmkp(-file(-this-dir))-(all|some)-tags-jump(-other-window):
+;;         Let user use a prefix arg to refresh tags list.  Add this info to doc string.
+;; 2012/01/14 dadams
+;;     Corrected bmkp-same-file-p: call to compare-strings.
+;; 2012/01/13 dadams
+;;     bmkp-same-file-p: Handle case-sensitivity for local files, at least (not yet done for remote).
+;; 2012/01/08 dadams
+;;     Added: bmkp-autonamed-this-buffer-bookmark-p.
+;;     bmkp-autotemp-bookmark-predicates: Updated doc string for *-autonamed-this-buffer-bookmark-p.
+;;     bmkp-autonamed-bookmark-for-buffer-p: Updated doc string to mention it just checks the name.
+;;     bmkp-autonamed-this-buffer-alist-only:
+;;       Use bmkp-this-buffer-p, not bmkp-autonamed-bookmark-for-buffer-p.
+;; 2011/12/30 dadams
+;;     Renamed bmkp-edit-bookmark to bmkp-edit-bookmark-name-and-file.
+;;     Added aliases: bmkp-bookmark-(data|name)-from-record.
+;;     Added: bmkp-get-bookmark-in-alist, bmkp-bookmark-record-from-name,
+;;            bmkp-edit-bookmark-records-(number|send|mode(-map)),
+;;            bookmark-alist-from-buffer (redefinition), bmkp-edit-bookmark-orig-record,
+;;            bmkp-rename-for-marked-and-omitted-lists.
+;;     Use new names (aliases) bmkp-bookmark-(data|name)-from-record.
+;;     bookmark-get-bookmark-record: Use redefinition for all Emacs versions (updated doc string).
+;;     bookmark-get-bookmark: Use bmkp-bookmark-record-from-name, with no MEMP check.
+;;     bookmark-store: Use bmkp-get-bookmark-in-alist to test whether bookmark exists.
+;;                     Set the bookmark name also, not just the data, for an existing bookmark.
+;;                     Unconditionally always put full bookmark on name as property bmkp-full-record.
+;;     bookmark-send-edited-annotation, bookmark-rename:
+;;       Do bookmark-bmenu-surreptitiously-rebuild-list only if no bmenu display window.
+;;     bookmark-rename:
+;;       Return OLD if if BATCHP is non-nil and NEW is nil.  Do not prompt for name if BATCHP.
+;;       Use bmkp-rename-for-marked-and-omitted-lists (rename in those lists too).
+;;       Unconditionally always put full bookmark on name as property bmkp-full-record.
+;;       Use bmkp-bookmark-record-from-name, not bookmark-get-bookmark, to get full record.
+;;     bookmark-delete, bmkp-edit-bookmark-name-and-file, bmkp-edit-bookmark-record,
+;;       bmkp-edit-tags(-send), bmkp-toggle-autonamed-bookmark-set/delete:
+;;         Use bmkp-get-bookmark-in-alist, not bookmark-get-bookmark.
+;;     bookmark-load: Call bmkp-refresh-menu-list only if display is visible, and with NO-MSG-P arg.
+;;     bookmark-show-annotation: Do not raise error if not a valid bookmark.
+;;     bmkp-edit-bookmark-record: Record bmkp-edit-bookmark-orig-record.  Strip properties from name.
+;;                                Updated edit-buffer text.
+;;     bmkp-edit-bookmark-record-send: Rewrote similarly to bmkp-edit-bookmark-records-send.  No args.
+;;     bmkp-default-bookmark-name:
+;;       Use bmkp-bookmark-record-from-name, not bookmark-get-bookmark, requiring membership in ALIST.
+;;     bmkp-save-menu-list-state, bmkp-get-tag-value: Added optional arg MSGP, and status messages.
+;;     bmkp-make-function-bookmark: Use bmkp-bookmark-record-from-name, not bookmark-get-bookmark.
+;;     bmkp-autonamed-bookmark(-for-buffer)-p:
+;;       Use bmkp-bookmark-name-from-record, not bookmark-get-bookmark and bookmark-name-from-*.
+;;     bmkp-get-tag-value, bmkp-has-tag-p: Removed unused arg MSGP.
+;;     bmkp-delete-bookmark-name-from-list:
+;;       For unpropertized DELNAME, Set BNAMES to result of delete call.
+;;       For propertized DELNAME, delete also unpropertized matches.
+;;     bmkp-(compilation|occur)-target-set-all: Do not prompt or show message unless MSGP.
+;;     bmkp-describe-bookmark-internals: Use a copy of the bookmark.  Strip properties from name.
+;;     bmkp-set-autonamed-regexp-buffer: Pass MSGP, do not hardcode.n
+;;     Doc string improvements.
+;; 2011/12/24 dadams
+;;     bmkp-refresh-menu-list: Added progress message.
+;;     bmkp-jump-bookmark-file: Pass NO-MSG-P arg to bookmark-load.
+;; 2011/12/21 dadams
+;;     Added: bmkp-orphaned(-local|-remote)-file-(alist-only|bookmark-p),
+;;            bmkp-dired-wildcards-bookmark-p.
+;;     bookmark-load:
+;;       Call (bmkp-refresh-menu-list (bookmark-bmenu-bookmark)), not (bmkp-bmenu-refresh-menu-list).
+;; 2011/12/19 dadams
+;;     bookmark-set, bmkp-handle-region-default:  Use line-end-position, not end-of-line + point.
+;; 2011/12/17 dadams
+;;     bmkp-remote-file-p:
+;;       If file-remote-p not available, match /...: (same as ffap-ftp-regexp).  Return match.
+;;     bmkp-same-file-p: Redefined to use new bmkp-remote-file-p.  Thx to M. Heerdegen & M. Albinus.
+;; 2011/12/15 dadams
+;;     bmkp-dired-this-dir-bookmark-p: Use file-name-directory, in case filename has wildcards.
+;; 2011/12/13 dadams
+;;     bmkp-handle-region-default: Limit buffer-substring-no-properties positions to point-min/max.
+;; 2011/12/06 dadams
+;;     bmkp-last-as-first-bookmark-file:
+;;       Removed autoload cookie to avoid void-variable error for bookmark-default-file.
+;;     bmkp-edit-bookmark, bookmark-rename: Use bmkp-completing-read-lax, not read-from-minibuffer.
+;; 2011/12/05 dadams
+;;     bmkp-this-buffer-p:
+;;       Do not use buffer-file-name (for Dired).  Wrap bookmark-buffer-file-name with condition-case.
+;;     bookmark-save: Swap write order, so last message is about the bookmark file, not customize.
+;; 2011/12/03 dadams
+;;     Renamed: bmkp-use-bookmark-file-create to bmkp-switch-bookmark-file-create.
+;;     Added: bmkp-last-as-first-bookmark-file, bookmark-maybe-load-default-file (redefinition),
+;;            bookmarks-already-loaded (redefinition), bmkp-default-bookmark-file.
+;;     bookmark-save: Update and save bmkp-last-as-first-bookmark-file.
+;;     bookmark-load: New default for reading file name, and require an existing file (match).
+;;                    Update and save bmkp-last-as-first-bookmark-file.  Update bmkp-sorted-alist.
+;;     bmkp-switch-bookmark-file (no longer used): New default for reading file name.
+;;     bmkp-switch-bookmark-file-create: Added optional arg INTERACTIVEP.  New default for reading
+;;       file name.  Use bookmark-load, not bmkp-switch-bookmark-file.  Require confirmation only for
+;;       new, empty file.  Added final message.
+;;     bmkp-switch-to-last-bookmark-file: Use bmkp-last-as-first-bookmark-file as first fallback.
+;;     bmkp-set-bookmark-file-bookmark: Use bmkp-read-bookmark-file-name, not read-file-name.
+;;                                      New default for reading file name.
+;;     bmkp-temporary-bookmarking-mode: Use bookmark-load, not bmkp-switch-bookmark-file.
+;;     Removed: bookmark-maybe-message.  Use only message now, not bookmark-maybe-message.
+;;     bmkp-autofile-set: For Emacs 23.3+, provide multiple defaults for file name.
+;; 2011/11/30 dadams
+;;     bmkp-same-file-p: Avoid having Tramp prompt for passwords, when possible.  Thx to M. Heerdegen.
+;;     bmkp-toggle-autotemp-on-set: Removed ARG (copy/paste typos).
+;; 2011/11/28 dadams
+;;     bmkp-set-bookmark-file-bookmark: Prompt user for bookmark name here, to make clear what it is.
+;; 2011/11/27 dadams
+;;     bookmark-write-file: If write error, do not overwrite message.  And show error msg for 4 sec.
+;; 2011/11/18 dadams
+;;     Renamed: bmkp-bookmark-image-bookmark-p to bmkp-image-bookmark-p.
+;;     Added: bmkp-image-alist-only, bmkp-image-jump(-other-window), bmkp-image-history.
+;;     bookmark-handle-bookmark: If bmk has handler but it's not a function, use default handler.
+;;     bmkp-autotemp-bookmark-predicates: Update doc string to include bmkp-image-bookmark-p.
+;;     bmkp-types-alist: Added entry for images.
+;; 2011/11/15 dadams
+;;     bookmark-relocate: Redefine without using old-*.  Update Dired location too.
+;;     Added: bmkp-cycle-this-file(/buffer)(-other-window),
+;;            bmkp-(next|previous)-bookmark-this-file(/buffer)(-repeat),
+;;            bmkp-this-file(/buffer)-bmenu-list, bmkp-this-file/buffer-alist-only.
+;;     Renamed bmkp-this-buffer-cycle-sort-comparer to bmkp-this-file/buffer-cycle-sort-comparer.
+;;     bmkp-this-buffer-p: Return nil if bookmark has a file diff from buffer.
+;;     bmkp-this-file-p:
+;;       Ensure bmkp-file-bookmark-p and bookmark-buffer-file-name.  Use bmkp-same-file-p.
+;; 2011/11/09 dadams
+;;     bmkp-jump-dired, bmkp-jump-man: Added bmkp-select-buffer-other-window to other-window fns.
+;; 2011/11/08 dadams
+;;     bmkp-edit-bookmark: For new file name, use read-file-name, not read-from-minibuffer.
+;; 2011/11/03 dadams
+;;     Renamed: bmkp-autoname-bookmark to bmkp-autoname-bookmark-function-default.
+;; 2011/11/01 dadams
+;;     Added: bmkp-temporary-jump(-other-window).
+;;     bmkp-bookmark-description: Title now indicates whether temporary.
+;; 2011/10/31 dadams
+;;     Added: bmkp-toggle-autotemp-on-set, bmkp-autotemp-all-when-set-p.
+;;     bookmark-set: If bmkp-autotemp-all-when-set-p call bmkp-make-bookmark-temporary.
+;; 2011/10/28 dadams
+;;     Added: bmkp-delete-temporary-no-confirm.
+;;     bmkp-delete-all-temporary-bookmarks: Rewrote (it was just a stub).
+;;     bmkp-bmenu-menubar-menu:
+;;       Added: bmkp-temporary-bookmarking-mode, bmkp-delete-all-temporary-bookmarks,
+;;              bmkp-bmenu-toggle-marked-temporary/savable.
+;;     bmkp-bmenu-show-menu: Added: bmkp-bmenu-show-only-temporary.
+;;     bmkp-bmenu-mark-menu:
+;;       Added: bmkp-bmenu-mark-temporary-bookmarks, bmkp-bmenu-mark-autonamed-bookmarks.
+;;     bmkp-bmenu-mouse-3-menu: Added: bmkp-bmenu-toggle-temporary.
+;;     bookmark-bmenu-mode: Updated doc string.
+;; 2011/10/27 dadams
+;;     Added: bmkp-autotemp-bookmark-predicates, bmkp-temporary-bookmarking-mode(-hook),
+;;            bmkp-delete-all-temporary-bookmarks, bmkp-make-bookmark-(savable|temporary),
+;;            bmkp-toggle-temporary-bookmark, bmkp-temporary-alist-only, bmkp-temporary-bookmark-p.
+;;     bookmark-set: Make bookmark temporary, if bmkp-autotemp-bookmark-predicates says to.
+;;     bookmark-write-file: Do not save temporary bookmarks (bmkp-temporary-bookmark-p).
+;; 2011/10/25 dadams
+;;     bmkp-empty-file: Added optional arg CONFIRMP.  By default, no confirmation if not interactive.
+;; 2011/08/09 dadams
+;;     Bind icicle-unpropertize-completion-result-flag to t for all calls to completing-read.
+;; 2011/08/07 dadams
+;;     Added: bmkp-guess-default-handler-for-file-flag, bmkp-file-bookmark-handlers.
+;;     bmkp-file-bookmark-p: Use bmkp-file-bookmark-handlers, which means also image-bookmark-jump.
+;;     bmkp-make-record-for-target-file (need to keep in sync with diredp-bookmark):
+;;       Instead of image-bookmark-make-record, use explicit function that includes file and type.
+;;     bmkp-default-handler-for-file:
+;;       Use bmkp-guess-default only if bmkp-guess-default-handler-for-file-flag is non-nil.
+;;     bmkp-default-handler-associations: Updated doc string.
+;; 2011/08/05 dadams
+;;     bmkp-file-bookmark-p: Allow handler to be bmkp-default-handler-for-file, e.g. for image files.
+;;     bmkp-all-tags-alist-only: Corrected.
+;;     bmkp-refresh-menu-list: Ensure BOOKMARK is a string.
+;;     bmkp-every: Removed unused binding.
+;; 2011/05/08 dadams
+;;     Just put some definitions in alphabetic order - no real change.
+;; 2011/04/25 dadams
+;;     bmkp-bookmark-description: Added optional arg NO-IMAGE.
+;;     bmkp-url-target-set: Protect url-get-url-at-point with fboundp.
+;;     bmkp-(file-target|autofile)-set, bmkp-autofile-(add|remove)-tags:
+;;       Added buffer-file-name as a default possibility.  Removed URL functions for that purpose.
+;; 2011/04/24 dadams
+;;     Added: bmkp-purge-notags-autofiles.
+;;     bookmark-delete: Redefined to accept either bookmark or name as arg.
+;;     bmkp-(url|file|compilation|occur)-target-set(-all), bmkp-autofile-(set|(add|remove)-tags):
+;;       Removed optional args when read prefix.
+;;     bmkp-occur-target-set-all: Made PREFIX arg optional too.
+;;     Added some missing autoload cookies.  Removed some from non-def sexps.
+;; 2011/04/21 dadams
+;;     Added: bmkp-copied-tags, bmkp-copy-tags, bmkp-paste-add-tags, bmkp-paste-replace-tags..
+;; 2011/04/20 dadams
+;;     bmkp-remove-all-tags: Added optional arg no-cache-update-p.
+;; 2011/04/19 dadams
+;;     bmkp-make-record-for-target-file: Fixed backquotes on lambdas.
+;; 2011/04/17 dadams
+;;     bmkp-edit-tags: Do not apply bmkp-full-tag to the tags.
+;; 2011/04/16 dadams
+;;     Added: bmkp-edit-tags(-send|-mode(-map)), bmkp-return-buffer.
+;;     bookmark-(rename|relocate|send-edited-annotation), bmkp-update-autonamed-bookmark,
+;;       bmkp-(add|remove(-all)-tags:
+;;         Wrap with-current-buffer around bmkp-refresh-menu-list.
+;;     bookmark-(store|rename|write-file): Test emacs-major-version, not just (boundp 'print-circle).
+;;     bmkp-autofile-add-tags: Fix interactive args - forgot to include DIR arg (= nil).
+;; 2011/04/15 dadams
+;;     Added: bmkp-autofile-alist-only, bmkp-autofile-bookmark-p.
+;; 2011/04/13 dadams
+;;     Added: bmkp-autofile-jump(-other-window) (aliases), bmkp-find-file(-other-window).
+;;     bmkp-find-file-(all|some)-tags(-regexp)(-other-window): Bind use-file-dialog to nil.
+;; 2011/04/12
+;;     Added: bmkp-bookmark-name-member, bmkp-names-same-bookmark-p, bmkp-sort-omit,
+;;            bmkp-remove-omitted, bmkp-delete-bookmark-name-from-list, bmkp-bookmark-a-file (alias),
+;;            bmkp-autofile-(add|remove)-tags, bmkp-(un)tag-a-file (aliases),
+;;            bmkp-get-autofile-bookmark, bmkp-find-file-(all|some)-tags(-regexp)(-other-window).
+;;     Removed: bmkp-remove-assoc-dups, bmkp-sort-and-remove-dups.
+;;     Applied renaming: bmkp-bmenu-omitted-list to bmkp-bmenu-omitted-bookmarks.
+;;     bookmark-store: Redefine for all Emacs versions now:
+;;       Put the bookmark on the name as property bmkp-full-record.  Use bmkp-maybe-save-bookmarks.
+;;       Return the bookmark.
+;;     bookmark-get-bookmark: Redefine for all Emacs versions now:
+;;       If BOOKMARK is a bookmark-name string that has property bmkp-full-record, return that value.
+;;     bookmark-send-edited-annotation: Make sure it's the annotation buffer that gets killed.
+;;     bookmark-default-handler: Return nil, like vanilla (but why?).
+;;     bookmark-location: Pass full bookmark to the various "get" functions.
+;;     bookmark-rename: Put bmkp-full-record property on new name.
+;;     bookmark-delete:
+;;       Use bmkp-delete-bookmark-name-from-list: If name has bmkp-full-record property, use that
+;;         with name to find bookmark to delete.
+;;       Pass full bookmark to unlight.
+;;     bmkp-edit-bookmark: Save if either is non-empty, not if both are.  Thx to Michael Heerdegen.
+;;     bmkp-edit-bookmark-record: Bind print-circle to t around pp.
+;;     bmkp-default-bookmark-name:
+;;       Use bookmark-name-from-full-record plus bookmark-get-bookmark, not assoc.
+;;       If BNAME is nil (no default) then do not try to look it up in alist.
+;;     bookmark-write-file: Unpropertize only for Emacs 20 or nil bmkp-propertize-bookmark-names-flag.
+;;                          Bind print-circle to t around pp.
+;;     bmkp-save-menu-list-state: Make it interactive (a command).  Bind print-circle.
+;;                                Use bmkp-maybe-unpropertize-bookmark-names on alists and name lists.
+;;                                Bind print-circle to t around pp.
+;;     bmkp-unomit-all: Use bmkp-delete-bookmark-name-from-list, not delete.
+;;     bmkp-dired-this-dir-bookmark-p: Use bmkp-same-file-p, not string=.
+;;     bmkp-url-target-set, bmkp-replace-existing-bookmark:: Return the bookmark.
+;;     bmkp-file-target-set:  Return bookmark.  Added arg MSGP: msg if no file yet.
+;;     bmkp-autofile-set:
+;;       Added DIR arg and MSGP arg: msg if no file yet.  Return the bookmark.
+;;       If read absolute file name, create bmk in its dir, not in default-directory.  Else use DIR.
+;;       Use bmkp-get-autofile-bookmark, so uses bmkp-same-file-p for each file part (not equal).
+;;     bmkp-marked-bookmark-p, bmkp-omitted-bookmark-p: Use bmkp-bookmark-name-member, not member.
+;;     bookmark-location: Pass full bookmark to the various "get" functions.
+;;     bmkp-choose-navlist-from-bookmark-list, bmkp-cycle-this-buffer:
+;;       Use bmkp-sort-omit, not bmkp-sort-and-remove-dups.
+;;     bmkp-bookmark-description, bmkp-describe-bookmark-internals: Add Bookmark `' to title.
+;;     bmkp-make-bookmark-list-record: Use bmkp-maybe-unpropertize-bookmark-names on lists.
+;;     bmkp-printable-p: Bind print-circle to t around prin1.
+;;     bmkp-delete-autonamed(-this-buffer)-no-confirm:
+;;       Do nothing if bookmarks not loaded.  Thx to Christoph Scholtes.
+;; 2011/04/03 dadams
+;;     Added: bmkp-make-record-for-target-file, bmkp-replace-existing-bookmark (not used).
+;;     bmkp-file-this-dir-bookmark-p: Corrected it to compare directory to default-directory.
+;;     bmkp-file-target-set: Added arg NO-OVERWRITE (pass to bookmark-store).
+;;                           Use (new) bmkp-make-record-for-target-file.
+;;     bmkp-autofile-set: Do nothing if bookmark with same name, file and dir exists.
+;;                        Else create one, even if the bookmark name is the same.
+;;                        You can have multiple autofile bookmarks with the same name (diff files).
+;; 2011/04/02 dadams
+;;     Added: bmkp-autofile-set, bmkp-file-this-dir-(all|some)-tags(-regexp)-jump(-other-window),
+;;            bmkp-file-this-dir-(all|some)-tags(-regexp)-alist-only.
+;; 2011/04/01 dadams
+;;     Moved key and menu bindings to (new) bookmark+-key.el.
+;;     Added: bmkp-(dired|file)-this-dir-alist-only, bmkp-(dired|file)-this-dir-bookmark-p,
+;;            bmkp-file-this-dir-jump(-other-window).
+;;     Renamed: bmkp-dired-jump-current(*) to bmkp-dired-this-dir-jump(*).
+;;     bmkp-dired-this-dir-jump(-other-window): Use bmkp-dired-this-dir-alist-only.
+;;     bmkp-types-alist: Added (dired|file)-this-dir.
+;;     Bound bmkp-(dired|file)-this-dir-jump to C-d and C-f in bookmark-jump(-other-window)-map.
+;;     bmkp-jump-dired, bmkp-jump-man: Treat null bmkp-jump-display-function as display-buffer.
+;; 2011/03/26 dadams
+;;     Added: bmkp-file-(all|some)-tags(-regexp)-(alist-only|jump(-other-window)).
+;;     bmkp-jump-menu: Added the new commands, but not Emacs 20, to avoid crash if byte-compiled.
+;;     bmkp-bookmark-jump*-other-window: Simplified doc strings - refer to same-window version.
+;; 2011/03/17 dadams
+;;     bmkp-describe-bookmark: Added 10-pixel margin around thumbnail image.
+;; 2011/03/11 dadams
+;;     Protect use of mouse-wheel-*-event with boundp.  Thx to Chris Poole.
+;; 2011/03/04 dadams
+;;     bmkp-bookmark-description, bmkp-describe-bookmark: Added clickable thumbnail to the help.
+;;     bmkp-bookmark-description: Split file name into dir & relname, so shorter line, in help.
+;; 2011/03/03 dadams
+;;     Added: bmkp-all-exif-data, bmkp-bookmark-image-bookmark-p.
+;;     bmkp-bookmark-description: Handle image EXIF data.
+;; 2011/01/03 dadams
+;;     Removed autoload cookies from non def* sexps and from define-key and define-prefix-command.
+;;     Added some missing autoload cookies for commands, in particular redefined standard commands.
+;; 2010/12/10 dadams
+;;     Added defalias for bookmark-name-from(-full)-record, to fix gratuitous Emacs name change.
+;; 2010/10/22 dadams
+;;     Uncommented key bindings for mouse wheel, since Emacs bug #6256 has now been fixed.
+;;     bmkp-repeat-command: Don't bother to let-bind repeat-previous-repeated-command,
+;;                          and use setq, not let, for last-repeatable-command. Thx to Stefan Monnier.
+;; 2010/09/28 dadams
+;;     Added: bmkp-delete-autonamed(-this-buffer)-no-confirm.
+;; 2010/09/25 dadams
+;;     Added: option bmkp-default-bookmark-name, bmkp-annotated-alist-only.
+;;     Added: bmkp-(next|previous)-*(-repeat), using macro bmkp-define-next+prev-cycle-commands.
+;;     bmkp-default-bookmark-name: Respect option.
+;;     bookmark-edit-annotation-mode, bookmark-edit-annotation:
+;;       Use bmkp-annotated-alist-only (and new bmkp-default-bookmark-name).
+;;     bookmark-send-edited-annotation:
+;;       End in orig buffer, not bmenu buffer.  Delete edit window.  Thx to Joe Bloggs.
+;; 2010/09/24 dadams
+;;     Added: bmkp-autonamed(-this-buffer)-jump(-other-window).  Bound to C-x j # (#|.) and menus.
+;;     Added, using bmkp-define-cycle-command:
+;;       bmkp-cycle-(autonamed|bookmark-list|desktop|dired|gnus|info|lighted|(local-|remote-)file|
+;;                   man|non-file|remote-file|specific-(buffers|files)|variable-list|url)
+;;                   (-other-window).
+;;     Added redefinitions: bookmark-edit-annotation(-mode).
+;;     Renamed: *varlist* to *variable-list*.
+;;     bmkp-autoname-format: Added ^ to anchor numeral at beginning.
+;;     bookmark--jump-via: Don't update autonamed if using w32 association.
+;;     bmkp-update-autonamed-bookmark: bmkp-refresh-menu-list only if buffer list is displayed.
+;;     *-(relocate|rename), *-update-autonamed-bookmark, *-remove-all-tags, *-(add|remove)-tags:
+;;       Don't create bookmark-list buffer if doesn't exist.
+;;     bookmark-show-(annotation|all-annotations): Restore selected window and frame focus.
+;;     bmkp-completing-read-(buffer|file)-name: Added optional NO-DEFAULT-P arg.
+;;     bmkp-describe-bookmark: Default to highlighted bookmarks on line, if there are any.
+;;     bmkp-specific-(buffers|files)-jump(-other-window): Allow empty input, to end loop.
+;;     bmkp-cycle: Ensure bmkp-current-nav-bookmark is a bookmark, else redefine.  Use %9d, not %d.
+;;     bmkp-cycle-other-window: Added optional STARTOVERP arg here too.
+;; 2010/09/20 dadams
+;;     bmkp-choose-navlist-of-type: Empty input means "any".
+;; 2010/09/16 dadams
+;;     bmkp-read-bookmark-file-name:
+;;       Removed extra default-filename in call to read-file-name.  Thx to Pedro Insua.
+;; 2010/08/22 dadams
+;;     Added: bmkp-regexp-filtered-annotation-alist-only.
+;; 2010/08/20 dadams
+;;     Added: bmkp-read-bookmark-file-name.
+;;     bookmark-save, bookmark-load, bmkp-switch-bookmark-file, bmkp-use-bookmark-file-create:
+;;       Use bmkp-read-bookmark-file-name.
+;; 2010/08/19 dadams
+;;     Require gnus-sum.el when compile (for macro).  Thx to S. Nemec.
+;; 2010/08/18 dadams
+;;     Removed eval-when-compile for bookmark+-lit.el.
+;;     Replaced defvar of bmkp-edit-bookmark-record-mode-map with a define-key after derived mode.
+;; 2010/08/17 dadams
+;;     bmkp-edit-bookmark: Made interactive.  Bound to C-x p E.  Added optional INTERNALP arg.
+;;     bmkp-info-bookmark-p: Return nil if a different handler.
+;; 2010/08/15 dadams
+;;     Moved bmkp-define-file-sort-predicate, bmkp-menu-bar-make-toggle to bookmark+-mac.el.
+;;     Require: bookmark.el, bookmark+-mac.el.
+;;     Require for compile: bookmark+-bmu.el, bookmark+-lit.el (soft).
+;;     Ensure this file is loaded before compiling.
+;;     bmkp-set-bookmark-file-bookmark: Added missing arg for error format string.
+;; 2010/08/08 dadams
+;;     bookmark-jump: Added optional arg DISPLAY-FUNCTION (Emacs 24).
+;;     bookmark-handle-bookmark:
+;;       Move non-default handler call outside condition-case.
+;;       Updated for Emacs 24: Use error condition bookmark-error-no-filename.  Added props for it.
+;;     bookmark-default-handler: Updated for Emacs 24:
+;;       Signal condition bookmark-error-no-filename, not file-error, and pass (stringp FILE).
+;;     bookmark-make-record-default: Added optional args NO-CONTEXT, POSITION (Emacs 24), and VISITS.
+;;     bookmark-load: Updated for Emacs 24: Wrap with abbreviate-file-name.
+;;     bmkp-jump-1: Allow arg to be a bookmark or its name.
+;;     bmkp-gnus-bookmark-p: Updated for Emacs 24: Added gnus-summary-bookmark-jump.
+;;     bmkp-jump-gnus: Different gnus-fetch-group call for Emacs 20, 21.
+;;     bmkp-make-(desktop|varlist|bookmark-(file|list))-record: Call *-record-default with NO-CONTEXT.
+;;     w3m-current-title: Use w3m-current-title as bookmark name.
+;;     bmkp-w3m-set-new-buffer-name, bmkp-jump-w3m*: Require w3m.
+;;     bmkp-make-gnus-record: Get bookmark name from gnus-summary-article-header.
+;;     Update for Emacs 24: Bypass bmkp specific Gnus, man, and woman code.
+;; 2010/08/06 dadams
+;;     Added (and bound the commands):
+;;       bmkp-(compilation|occur)-target-set(-all), bmkp-(file|url)-target-set,
+;;       bmkp-default-handler-associations, bmkp-compilation-file+line-at,
+;;       bmkp-default-handler-(for-file|user), bmkp-sound-jump.
+;;     bmkp-occur-create-autonamed-bookmarks: Do not define it  for Emacs < 22.  Protect wrt POS, BUF.
+;;     Added to Bookmark menu: bmkp-(file|url)-target-set, bmkp-set-(bookmark-file|desktop)-bookmark.
+;; 2010/08/04 dadams
+;;     bmkp-edit-bookmark: Use new bookmark name for update of dired-directory.  Thx to Kai Tetzlaff.
+;; 2010/08/03 dadams
+;;     bmkp-make-url-browse-record: Remove text properties from URL arg.
+;; 2010/07/17 dadams
+;;     Added: bmkp-url-jump-(other-window), bmkp-url(-browse)-(alist-only|bookmark-p), bmkp-url-cp,
+;;            bmkp-url-history, bmkp-make-url-browse-record, bmkp-jump-url-browse.
+;;     bmkp-sort-comparer: Use bmkp-url-cp, not bmkp-w3m-cp.
+;;     bmkp-types-alist: w3m -> url.
+;;     bookmark-alist: Updated doc string to mention LOCATION.  W3M -> URL.
+;;     bmkp-bookmark-description: Treat URL.  Set no-position-p depending on start.
+;;     Bind bmkp-url-jump*.  Replace W3M by URL in menu items.
+;; 2010/07/14 dadams
+;;     Created from bookmark+.el code.
+ 
+;;;(@* "CHANGE LOG FOR `bookmark+-bmu.el'")
+;;
+;; 2022/01/14 dadams
+;;     bmkp-bmenu-edit-marked: Enable undo inside with-current-buffer (not significant).
+;; 2021/09/19 dadams
+;;     Moved defgroup from here to bookmark+.el, for new defcustom bmkp-bmenu-buffer.
+;;     Everywhere: Use bmkp-bmenu-buffer, not vanilla bookmark-bmenu-buffer.
+;;     bmkp-bmenu-barf-if-not-in-menu-list: Test mode with derived-mode-p; don't test buffer name.
+;; 2021/08/18 dadams
+;;     Applied renaming of bmkp-auto-idle-bookmark-mode to bmkp-automatic-bookmark-mode.
+;; 2021/04/16 dadams
+;;     bookmark-bmenu-execute-deletions:
+;;       Use bmkp-get-bookmark, not bookmark-get-bookmark, but in vanilla-compatible way.
+;;     bmkp-bmenu-make-sequence-from-marked, bmkp-bmenu-remove-tags-from-marked,
+;;       bmkp-bmenu-propertize-item, bmkp-bmenu-marked-or-this-or-all:
+;;         Use bmkp-get-bookmark, not bookmark-get-bookmark.
+;; 2021/03/05 dadams
+;;     Face bmkp-no-local: changed default to orange background, from yellow foreground.
+;; 2021/03/04 dadams
+;;     bmkp-bmenu-describe-marked: Typo - bmkp-describe-bookmark-marked -> bmkp-bmenu-describe-marked.
+;; 2020/12/29 dadams
+;;     Wrap soft-require of menu-bar+.el in null condition-case, because it soft-requires Bookmark+.
+;; 2020/11/27 dadams
+;;     bmkp-bmenu-define-command, bmkp-bmenu-define-full-snapshot-command:
+;;       Use copy-sequence for lists, because some code modifies the list structure.
+;;       If command already defined then prompt to overwrite its definition (replace all existing).
+;;     bmkp-bmenu-define-full-snapshot-command:
+;;       Bind bookmark-alist to non-nil bmkp-latest-bookmark-alist. NB: Contradicts 2015-02-22 change.
+;; 2020/11/26 dadams
+;;     bmkp-bmenu-read-filter-input:
+;;       Set, don't bind, bmkp-bmenu-filter-(title|function).  Restore them and the pattern, if C-g.
+;; 2020/11/06 dadams
+;;     bmkp-bmenu-read-filter-input:
+;;       Bind prefix-command-echo-keystrokes-functions to nil.  See Emacs bug #44500.
+;; 2020/07/04 dadams
+;;     Changed all references to `C-x p' to `C-x x'.
+;;     Replaced string *Bookmark List* with bookmark-bmenu-buffer (for Emacs 28).
+;; 2020/01/26 dadams
+;;     Added: bmkp-bmenu-sort-annotated-before-unannotated (bound to s a).
+;; 2020/01/22 dadams
+;;     bookmark-bmenu-list: Restore bookmark-bmenu-list to saved value, last-previous-bookmark-file.
+;;     bookmark-bmenu-mode: Added to doc: *-(switch-to-bookmark-file|save-bookmarks)-this-file/buffer.
+;;     bmkp-bmenu-bookmark-file-menu: Added bmkp-switch(-to-last)-bookmark-file(-create).  Reordered.
+;; 2020/01/15 dadams
+;;     Added: bmkp-bmenu-edit-annotations-for-marked.
+;;     Bind bookmark-bmenu-(show|edit)-annotation, bookmark-bmenu-show-all-annotations,
+;;          bmkp-bmenu-edit-annotations-for-marked to new prefix key a (a, e, A, >) and in
+;;          bmkp-bmenu-(edit|show)-menu and bmkp-bmenu-mouse-3-menu.
+;;     No longer bind bmkp-bmenu-show-or-edit-annotation.
+;; 2019/10/29 dadams
+;;     bookmark-bmenu-relocate: Ensure that arg to bookmark-relocate is not nil.
+;;     bookmark-bmenu-bookmark: Mention in doc: nil return if no bookmark.
+;;     bookmark-bmenu-show-annotation, bmkp-bmenu-w32-open-with-mouse: Raise error if no bookmark.
+;;     bmkp-bmenu-show-menu: Enable bookmark-bmenu-show-annotation only if there is a bookmark.
+;; 2019/08/13 dadams
+;;     Added bmkp-bmenu-clone-bookmark, bmkp-bmenu-copy-bookmark (alias).  Bound to M-n in bmk list.
+;;       Added it to bmkp-bmenu-menubar-menu, bmkp-bmenu-mouse-3-menu.
+;; 2019/08/09 dadams
+;;     bmkp-file-handler: Changed default to LightBlue background.
+;; 2019/05/19 dadams
+;;     Bind print-gensym wherever we bind print-circle.
+;; 2019/04/23 dadams
+;;     Added bmkp-bmenu-edit-menu.
+;;     Moved bmkp-bmenu-edit-marked to bmkp-bmenu-edit-menu from main Bookmark+ menu.
+;;     bmkp-bmenu-show-menu: Added bookmark-bmenu-show-annotation.
+;; 2018/11/24 dadams
+;;     bookmark-bmenu-other-(window|frame):
+;;       Added missing bookmark-name arg to b-j-o-(window|frame).  Thx to Alan Wehmann.
+;;     Added: bmkp-bmenu-load-marking,  bmkp-bmenu-load-marking-unmark-first.
+;;     bmkp-bmenu-(bookmark-file|mark)-menu: Added bmkp-bmenu-load-marking(-unmark-first).
+;; 2018/10/10 dadams
+;;     Added: bookmark-bmenu-other-frame.
+;;     bookmark-bmenu-mode: Added bookmark-bmenu-other-frame to doc string.
+;; 2018/09/21 dadams
+;;     Added: bmkp--pop-to-buffer-same-window.  (Added also to bookmark+-lit.el.)
+;;     bookmark-bmenu-2-window, bookmark-bmenu-this-window:
+;;       Use bmkp--pop-to-buffer-same-window, not switch-to-buffer.
+;; 2018/08/28 dadams
+;;     bmkp-bmenu-read-filter-input: Do not pass non-characterp value to text-char-description.
+;; 2017/10/27 dadams
+;;     bookmark-bmenu-mode: Added to doc string: bmkp-bmenu-paste-(add|replace)-tags.
+;; 2017/10/14 dadams
+;;     All EWW stuff is for Emacs 25+, not Emacs 24.4+.
+;; 2017/10/08 dadams
+;;     bmkp-bmenu-describe-marked: Bind print-(circle|length|level) so pp-to-string prints all.
+;; 2017/07/03 dadams
+;;     Added: bmkp-bmenu-sort-by-Info-position.
+;;     Renamed bmkp-bmenu-sort-by-Info-location to bmkp-bmenu-sort-by-Info-node-name.
+;;     bookmark-bmenu-mode: Updated doc string for Info-bookmark sorting.
+;;     bmkp-bmenu-sort-by-bookmark-type, bmkp-bmenu-sort-by-Info-node-name:
+;;       Applied renaming of bmkp-info-cp to bmkp-info-node-name-cp.
+;;     Bind bmkp-bmenu-sort-by-Info-position to s I.
+;;     bmkp-bmenu-sort-menu:
+;;       Added bmkp-bmenu-sort-by-Info-position.  Renamed By Info Node to By Info Node Name.
+;; 2017/03/30 dadams
+;;     bmkp-bmenu-mark-*-bookmarks:
+;;       Added optional arg MSGP.  Pass it to bmkp-bmenu-mark-bookmarks-satisfying.
+;;     bmkp-bmenu-mark-(orphaned-local-)file-bookmarks: Made argument ARG optional.
+;;     bmkp-bmenu-mark-bookmarks-satisfying: Added missing \ni to interactive spec.
+;; 2017/01/10 dadams
+;;     Renamed bmkp-toggle-allow-multi-tabs-for-w3m to bmkp-toggle-w3m-allow-multiple-buffers.
+;;     bmkp-bmenu-toggle-menu: Added bmkp-toggle-eww-allow-multiple-buffers.
+;; 2017/01/08 dadams
+;;     Use the term "entry", not "property" everywhere, for bookmark entries (fields).
+;; 2017/01/07 dadams
+;;     bmkp-bmenu-copy-marked-to-bookmark-file: Use bookmark-file-coding-system (Emacs bug #25365).
+;; 2017/01/02 dadams
+;;     bmkp-bmenu-mouse-3-menu: Added menu item Store Org Link.
+;; 2016/12/31 dadams
+;;     Added: bmkp-bmenu-mark-non-invokable-bookmarks, bmkp-bmenu-show-only-non-invokable-bookmarks.
+;;       Bound them to nM and nS.  Added them to menus bmkp-bmenu-(mark|show)-types-menu.
+;;     bookmark-bmenu-mode: Include non-invokable bookmarks in doc string.
+;;     bmkp-bmenu-propertize-item: Handle non-invokable bookmarks.
+;; 2016/11/23 dadams
+;;     bookmark-bmenu-mode: Doc string cleanup.
+;;     bookmark-bmenu-list, bmkp-bmenu-copy-marked-to-bookmark-file:
+;;       Raise an error if we have a directory, not a file.
+;;     bmkp-bmenu-create-bookmark-file-from-marked: Ensure that FILE is not a directory.
+;; 2016/11/18 dadams
+;;     Support Emacs 24.[45] too.
+;; 2016/11/15 dadams
+;;     bmkp-*eww-*: Ensure that EWW code is only for Emacs 25+.
+;; 2016/11/14 dadams
+;;     Added: bmkp-bmenu-mark-eww-bookmarks, bmkp-bmenu-show-only-eww-bookmarks.
+;;     bookmark-bmenu-mode: Added EWW to doc.
+;;     Bound bmkp-bmenu-mark-eww-bookmarks to WEM, bmkp-bmenu-show-only-eww-bookmarks to WES.
+;;     Change bmkp-bmenu-mark-w3m-bookmarks to W3M, bmkp-bmenu-show-only-w3m-bookmarks binding to W3S.
+;;     bmkp-bmenu-mark-types-menu, bmkp-bmenu-show-types-menu: Support EWW.
+;; 2016/06/24 dadams
+;;     bookmark-bmenu-execute-deletions: Delete bookmark on the current line if none flagged/marked.
+;; 2016/06/23 dadams
+;;     bmkp-bmenu-(add|remove)-tags-(to|from)-marked, bmkp-bmenu-paste-(add|replace)-tags-for-marked:
+;;       Call bmkp-maybe-save-bookmarks (after the iteration).  Thx to Alan Wehmann.
+;; 2016/06/21 dadams
+;;     bmkp-bmenu-add-tags-to-marked, bmkp-bmenu-remove-tags-from-marked,
+;;       bmkp-bmenu-paste-(add|replace)-tags-to-marked:
+;;         Put bookmark-save-flag let-binding around iteration only, so modification is recorded etc.
+;; 2016/06/11 dadams
+;;     bmkp-bmenu-list-1, bookmark-bmenu-hide-filenames:
+;;       Use string-width, not length.  Thx to Toshikazu Nakamura.
+;; 2015/11/07 dadams
+;;     bmkp-bmenu-copy-marked-to-bookmark-file: Added missing zerop test for No-changes case.
+;;     bmkp-bmenu-create-bookmark-file-from-marked:
+;;       Added missing MOVEP arg in call to bmkp-bmenu-copy-marked-to-bookmark-file.
+;; 2015/11/02 dadams
+;;     bmkp-bmenu-copy-marked-to-bookmark-file:
+;;       If modified, prompt to save bookmark file copied from, before copying.
+;;       For copy (not move): reload the original bookmark file, then refresh display from it.
+;; 2015/10/31 dadams
+;;     bmkp-bmenu-move-marked-to-bookmark-file:
+;;       Just call bmkp-bmenu-copy-marked-to-bookmark-file.  It now deletes moved and refreshes list.
+;;     bmkp-bmenu-copy-marked-to-bookmark-file:
+;;       Added arg MOVEP.  If move, delete before refresh list (deletes bmks returned in IMPORTED). 
+;; 2015/06/26 dadams
+;;     Added: bmkp-bmenu-mark-function-bookmarks, bmkp-bmenu-show-only-function-bookmarks.
+;;            Bound the to Q M and Q S.  Added to bmkp-bmenu-show-types-menu.
+;;     bookmark-bmenu-mode: Updated the doc string for them.
+;;     bmkp-bmenu-show-only(-orphaned-local)-file-bookmarks: Made ARG optional.
+;; 2015/05/15 dadams
+;;     Fixed typo: bmkp-bmenu-show-only-lighted -> bmkp-bmenu-show-only-lighted-bookmarks everywhere.
+;; 2015/04/15 dadams
+;;     bmkp-bmenu-describe-this-bookmark: save-selected-frame -> save-selected-window.
+;; 2015/03/20 dadams
+;;     Added: bmkp-bmenu-show-this-annotation+move-down, bmkp-bmenu-show-this-annotation+move-up,
+;;            bmkp-bmenu-kill-annotation, bmkp-remap.
+;;     Bind bmkp-bmenu-show-this-annotation+move-(down|up) to M-down, M-up.
+;;     bmkp-bmenu-describe-this+move-(down|up): Move first, then describe, not reverse.
+;;     bmkp-bmenu-describe-this-bookmark: Wrap with save-selected-frame.
+;; 2015/02/22 dadams
+;;     Moved to bookmark+-1.el from here:
+;;       bmkp-reset-bmkp-store-org-link-checking-p, bmkp-store-org-link-checking-p.
+;;       Advice of org-store-link (not needed for bmkp-bmenu-store-org-link).
+;;     Soft-require org.el when compile, for org-add-link-type.
+;;     bmkp-bmenu-store-org-link:
+;;       Removed bmkp-store-org-link-checking-p (needed only for bmkp-store-org-link).
+;;       Link type changed from bookmark-other-window to bookmark-other-win.
+;;     Fix for lost annotation etc. edit the first time after showing display list:
+;;       bookmark-bmenu-list, bmkp-bmenu-define-full-snapshot-command:
+;;         Bind bookmark-alist to result of bmkp-refresh-latest-bookmark-list - do not just bind it to
+;;           bmkp-latest-bookmark-alist if available.  (NOT SURE THIS IS RIGHT.)
+;;       bmkp-bmenu-list-1:
+;;         Removed update of bmkp-latest-bookmark-alist when not filteredp.  (NOT SURE THIS IS RIGHT.)
+;;     bmkp-bmenu-menubar-menu:
+;;       Toggle menu:
+;;         Moved Toggle menu higher.
+;;         Moved bmkp-toggle-save-desktop-before-switching with other autosaving menu items.
+;;         Added bmkp-toggle-auto-light-when-jump-menu.  
+;;         Moved temporary bookmark stuff lower, after display-list stuff.
+;;         bmkp-toggle-saving-menu-list-state: Corrected help text - affects also being able to save.
+;;       Moved bmkp-list-defuns-in-commands-file with other help stuff.
+;; 2015/02/21 dadams
+;;     Added: bmkp-bmenu-store-org-link, bmkp-reset-bmkp-store-org-link-checking-p,
+;;            bmkp-store-org-link-checking-p.
+;;     Add bmkp-bmenu-store-org-link to org-store-link-functions.
+;;     Advise org-store-link with bmkp-reset-bmkp-store-org-link-checking-p.
+;;     Added bookmark(-other-window) link types via org-add-link-type.
+;; 2015/02/08 dadams
+;;     Added: bmkp-bmenu-show-only-untagged-bookmarks.  Added it to bmkp-bmenu-show-types-menu.
+;;     Renamed: bmkp-bmenu-*icicle-* to bmkp-bmenu-icicles-*,
+;;              bmkp-bmenu-show-only-*- to bmkp-bmenu-show-only-*-bookmarks.
+;;     Use new macro bmkp-define-show-only-command for the simple bmkp-bmenu-show-only-* commands.
+;; 2014/12/18 dadams
+;;     bmkp-bmenu-show-only-specific-file: Restore vars if error.
+;; 2014/12/04 dadams
+;;     *-dired-marked, *-move-marked-to-bookmark-file, *-copy-marked-to-bookmark-file,
+;;       *-create-bookmark-file-from-marked, *-set-bookmark-file-bookmark-from-marked,
+;;       *-(i)search-marked-bookmarks(-regexp), *-query-replace-marked-bookmarks-regexp,
+;;       *-set-tag-value-for-marked, *-add-tags-to-marked, *-remove-tags-from-marked,
+;;       *-paste-(add|replace)-tags-to-marked, *-relocate-marked, *-edit-marked, *-describe-marked:
+;;         Added arg INCLUDE-OMITTED-P.
+;; 2014/11/09 dadams
+;;     bookmark-bmenu-show-annotation: Updated doc string to reflect updated bookmark-show-annotation.
+;; 2014/08/22 dadams
+;;     bmkp-looking-at-p: Do not defalias to Emacs looking-at-p because that is a defsubst.
+;; 2014/07/20 dadams
+;;     Protect key bindings for bmkp-bmenu-highlight-menu by boundp.
+;; 2014/07/12 dadams
+;;     Added: bmkp-bmenu-relocate-marked.  Bound to M-R.  Added it to bmkp-bmenu-menubar-menu.
+;; 2014/07/11 dadams
+;;     bmkp-bmenu-highlight-menu: Added item Toggle Autofile Highlighting in Dired.
+;;     bmkp-bmenu-toggle-menu: Added item Autofile Highlighting in Dired.
+;; 2014/07/06 dadams
+;;     Toggle submenu: added lots, improved.
+;; 2014/07/05 dadams
+;;     Added: bmkp-bmenu-create-bookmark-file-from-marked (bound to Y > 0),
+;;            bmkp-bmenu-set-bookmark-file-bookmark-from-marked, bmkp-bmenu-bookmark-file-menu.
+;;     Moved bookmark-file stuff to Bookmark File submenu.
+;;     bookmark-bmenu-mode: Updated doc string.
+;;     bmkp-bmenu-dired-marked: Use bmkp-bmenu-marked-or-this-or-all, not bmkp-marked-bookmarks-only.
+;;     bmkp-bmenu-marked-or-this-or-all: Added optional arg INCLUDE-OMITTED-P - else removed omitted.
+;; 2014/07/04 dadams
+;;     Added to Bookmark+ menu: bmkp-bmenu-(copy|move)-marked-to-bookmark-file.
+;; 2014/07/03 dadams
+;;     Added: bmkp-bmenu-copy-marked-to-bookmark-file, bmkp-bmenu-move-marked-to-bookmark-file.
+;;            Bound to Y > + and Y > -.
+;;     bookmark-bmenu-mode: Mention bmkp-bmenu-(copy|move)-marked-to-bookmark-file in doc string.
+;;     bookmark-bmenu-execute-deletions, bmkp-bmenu-delete-marked:: Added optional arg NO-CONFIRM-P.
+;;     bmkp-bmenu-define(-full-snapshot|jump)-command: Changed to C-c C-c, C-c C-S-c, C-c C-j.
+;;     bmkp-bmenu-show-all: Mention C-u g in doc string.
+;; 2014/06/30 dadams
+;;     bmkp-bmenu-mouse-3-menu:
+;;       Bind bmkp-bmenu-flag-for-deletion, not bookmark-bmenu-delete.  See Emacs bug #17888.
+;; 2014/06/26 dadams
+;;     bmkp-bmenu-show-only-omitted:
+;;       Use bmkp-bmenu-omit/unomit-marked, not bmkp-bmenu-unomit-marked, in doc string.
+;;     bmkp-bmenu-remove-tags-from-marked:
+;;       Typo in interactive spec: allp -> current-prefix-arg.  Thx to Alan Wehmann.
+;; 2014/06/21 dadams
+;;     Added: bmkp-no-jump, bmkp-bmenu-mark-bookmark-list-bookmarks,
+;;       bmkp-bmenu-mark-icicle-search-hits-bookmarks, bmkp-bmenu-show-only-bookmark-lists,
+;;       bmkp-bmenu-show-only-icicle-search-hits.
+;;     bookmark-bmenu-list, bookmark-bmenu-mode: Updated doc string, for additions.
+;;     bmkp-bmenu-mode-status-help: Updated for no-jump (used for Icicles search hits bookmarks).
+;;     bmkp-bmenu-propertize-item: Handle Icicles search hits bookmarks.
+;;     Bind *-bmenu-mark-icicle-search-hits-bookmarks, *-bmenu-show-only-icicle-search-hits: i M, i S.
+;;     Bind bmkp-bmenu-mark-bookmark-list-bookmarks, bmkp-bmenu-show-only-bookmark-lists: Z M, Z S.
+;;     bmkp-bmenu-mark-types-menu:
+;;       Added bmkp-bmenu-mark-icicle-search-hits-bookmarks, bmkp-bmenu-mark-bookmark-list-bookmarks.
+;;     bmkp-bmenu-show-types-menu:
+;;       Added bmkp-bmenu-show-only-icicle-search-hits, bmkp-bmenu-show-only-bookmark-lists.
+;; 2014/06/20 dadams
+;;     bmkp-define-tags-sort-command: Load bookmark+-mac.el(c) in interactive spec.
+;; 2014/05/27 dadams
+;;     bmkp-bmenu-mode-status-help, bmkp-bmenu-describe-marked:
+;;       Use bmkp-with-help-window, not with-output-to-temp-buffer (Emacs 24.4+ silliness).
+;; 2014/04/02 dadams
+;;     bmkp-bmenu-copy-tags, bmkp-bmenu-paste-replace-tags(for-marked):
+;;       Added Note to doc string about pasting an empty list of tags.
+;;     bmkp-bmenu-tags-menu: Added item Copy Tags from This Bookmark for bmkp-bmenu-copy-tags.
+;;     bmkp-bmenu-mouse-3-menu: Added :active bmkp-copied-tags for bmkp-bmenu-paste-add-tags.
+;; 2014/04/01 dadams
+;;     Added: bmkp-bmenu-list-tags-of-marked.
+;;       Bind it to T > l in bookmark-bmenu-mode-map.
+;;       Add it to bmkp-bmenu-tags-menu.
+;;     bookmark-bmenu-mode: List bmkp-bmenu-list-tags-of-marked in doc string.
+;; 2014/03/29 dadams
+;;     Added variable bmkp-bmenu-define-command-history.
+;;     bmkp-bmenu-define(-jump-marked|-full-snapshot)-command:
+;;       Removed quote before bmkp-bmenu-define-command-history.
+;;     Toggle submenu: Use bmkp-menu-bar-make-toggle.
+;; 2014/03/28 dadams
+;;     bmkp-bmenu-describe-marked: Apply bmkp-sort-omit, to show bookmarks in the current sort order.
+;; 2014/03/23 dadams
+;;     Added: bmkp-bmenu-delete-menu, bmkp-bmenu-mark-types-menu, bmkp-bmenu-search-menu,
+;;            bmkp-bmenu-show-types-menu, bmkp-bmenu-toggle-menu.  Move menu items there from top.
+;;     bookmark-bmenu-mode-map:
+;;       Bind jump commands to j prefix and J prefix (like C-x 4 j and C-x j).
+;;       Bind bookmark-bmenu-locate to C-S-l, since w is used as a prefix key now.
+;;     bookmark-bmenu-mode: New jump bindings.  Added bmkp-bmenu-copy-tags.
+;; 2014/03/21 dadams
+;;     bookmark-bmenu-mode: List also global bindings for tag commands.
+;; 2014/03/10 dadams
+;;     bmkp-maybe-unpropertize-bookmark-names: Remove prop face & Icicles props, in any case.
+;;     bmkp-bmenu-define(-jump-marked|-full-snapshot)-command, bmkp-define-tags-sort-command:
+;;       Bind print-circle to bmkp-propertize-bookmark-names-flag, not t, to avoid string reuse.
+;; 2013/12/13 dadams
+;;     bmkp-bmenu-mode-line:
+;;       To avoid Emacs crashes from bug #12867: Do not define it for Emacs 22-23, and wrap
+;;                                               condition-case around the whole function body.
+;; 2013/12/11 dadams
+;;     bmkp-bmenu-mode-line: Protect %360l (line) hack with condition-case.
+;; 2013/10/07 dadams
+;;     bmkp-bmenu-edit-marked: If no marked bmks, mark the current line bmk, to start with.
+;;                             Use correct buffer when go to point-min.
+;; 2013/08/09 dadams
+;;     Added: bmkp-looking-at-p.  Use it instead of looking-at, everywhere.
+;; 2013/07/02 dadams
+;;     Added to menu-bar Edit menu: bmkp-set-snippet-bookmark, bmkp-snippet-to-kill-ring.
+;; 2013/06/30 dadams
+;;     Added: bmkp-snippet, bmkp-bmenu-show-only-snippets, bmkp-bmenu-mark-snippet-bookmarks.
+;;     bookmark-bmenu-list: Added snippet info to doc string.
+;;     bmkp-bmenu-mode-status-help: Cover snippets too.
+;;     Bind bmkp-bmenu-(mark-snippet-bookmarks|show-only-snippets) to w M, w S.  Add to menus.
+;; 2013/06/29 dadams
+;;     bmkp-bmenu-regexp-mark, bmkp-bmenu-search-marked-bookmarks-regexp,
+;;       bmkp-bmenu-(un)mark-bookmarks-tagged-regexp:
+;;         Use bmkp-read-regexp in interactive spec.
+;;     bmkp-bmenu-mode-status-help: Ensure that we have a supported image before calling insert-image.
+;; 2013/06/09 dadams
+;;     bmkp-bmenu-mode-line-string: Added missing let-binding for REGEXP.
+;;     Added vacuous defvars to suppress free-var warnings.
+;; 2013/05/28 dadams
+;;     Renamed: bmkp-bmenu-edit-bookmark-name-and-file to bmkp-bmenu-edit-bookmark-name-and-location.
+;; 2013/05/28 dadams
+;;     bmkp-bmenu-list-1: Do not call put-image if create-image returns nil.
+;; 2013/05/15 dadams
+;;     Moved here from bookmark+-1.el: bmkp-string-match-p.
+;;     Use bmkp-string-match-p instead of string-match wherever appropriate.
+;; 2013/04/10 dadams
+;;     bmkp-bmenu-make-sequence-from-marked: Redefine using bmkp-set-sequence-bookmark (new).
+;; 2013/01/07 dadams
+;;     bookmark-bmenu-mode:
+;;       Added: bmkp-bmenu-set-tag-value-for-marked, bmkp-bmenu-paste-(add|replace)-tags-for-marked.
+;;       Mention C-u = all, for marked.
+;; 2013/01/04 dadams
+;;     bmkp-bmenu-show-only-tagged: Corrected filter function.
+;; 2012/11/14 dadams
+;;     bmkp-bmenu-mode-line: Added mode-line-buffer-identification.
+;; 2012/11/12 dadams
+;;     Added: bmkp-bmenu-marked-or-this-or-all.
+;;     bmkp-bmenu-isearch-marked-bookmarks(-regexp), bmkp-bmenu-search-marked-bookmarks-regexp,
+;;       bmkp-bmenu-query-replace-marked-bookmarks-regexp, bmkp-bmenu-set-tag-value-for-marked,
+;;       bmkp-bmenu-add-tags-to-marked, bmkp-bmenu-remove-tags-from-marked,
+;;       bmkp-bmenu-paste-(add|replace)-tags-(to|for)-marked, bmkp-bmenu-edit-marked,
+;;       bmkp-bmenu-describe-marked:
+;;         Make it work for current bookmark if none marked.
+;;     bmkp-bmenu-isearch-marked-bookmarks(-regexp), bmkp-bmenu-search-marked-bookmarks-regexp,
+;;       bmkp-bmenu-set-tag-value-for-marked, bmkp-bmenu-add-tags-to-marked,
+;;       bmkp-bmenu-remove-tags-from-marked, bmkp-bmenu-paste-(add|replace)-tags-(to|for)-marked,
+;;       bmkp-bmenu-edit-marked:
+;;         Make it work for all bookmarks if use prefix arg.
+;;     Protect all calls to bmkp-bmenu-mode-line with fboundp, for Emacs 20.
+;; 2012/11/11 dadams
+;;     Added: bmkp-bmenu-mode-line, bmkp-bmenu-mode-line-string.
+;;     Removed: bmkp-bmenu-nb-marked-in-mode-name (replaced by bmkp-bmenu-mode-line - shows more).
+;;     Removed faces bmkp-mode-line-marked, bmkp-mode-line-flagged.
+;;     bookmark-bmenu-(delete|(un)mark), bmkp-bmenu-list-1: Call bmkp-bmenu-mode-line.
+;;     bookmark-bmenu-execute-deletions: Inhibit saving until all are deleted, then save.
+;;     bmkp-bmenu-mode-status-help: Show > and D using their faces, bmkp->-mark, bmkp-D-mark.
+;;                                  Use "" if bmkp-current-sort-order (new version) returns nil.
+;; 2012/10/09 dadams
+;;     Made all autoload cookies explicitly load bookmark+.el(c).  Should help ELPA (e.g. MELPA).
+;; 2012/09/29 dadams
+;;     Added: bmkp-maybe-unpropertize-string.
+;;     bmkp-maybe-unpropertize-bookmark-names: Added optional arg COPY.
+;;     bmkp-bmenu-define(-jump-marked|-full-snapshot|-tags-sort)-command:
+;;       Bind print-circle, version-control, require-final-newline.
+;;       Use find-file-noselect & write-file, not write-region.
+;;     bmkp-bmenu-define-jump-marked-command: Use bmkp-maybe-unpropertize-bookmark-names on bookmarks.
+;;     bmkp-bmenu-define-full-snapshot-command:
+;;       Copy shared bookmark lists and single strings, to avoid circular refs.
+;;       Expand file names and use convert-standard-filename, for bookmark file names.
+;; 2012/09/28 dadams
+;;     Added: bmkp-bmenu-jump-to-marked.
+;;     Renamed: bmkp-bmenu-w32-open-select to bmkp-bmenu-w32-jump-to-marked.
+;;     Replace bookmark-bmenu-select with bmkp-bmenu-jump-to-marked, everywhere.
+;;     bmkp-bmenu-w32-open-with-mouse:
+;;       Rewrote to directly call bookmark-handle-bookmark, jump-fn, and show annotations.
+;; 2012/09/03 dadams
+;;     bookmark-bmenu-toggle-filenames: Added missing nil FORCE arg.
+;;     bmkp-bmenu-list-1: Call bookmark-bmenu-toggle-filenames with NO-MSGP arg.
+;;     Removed: bmkp-bmenu-filter-prompt.  bmkp-bmenu-read-filter-input: hard-code the prompt.
+;; 2012/06/26 dadams
+;;     Moved here from bookmark+-mac.el: bmkp-assoc-delete-all, bmkp-replace-regexp-in-string.
+;;     Wrapped require of bookmark+-mac.el in eval-when-compile.
+;; 2012/06/21 dadams
+;;     Added: bmkp-bmenu-nb-marked-in-mode-name.  Added to bookmark-bmenu-mode-hook.
+;;     Try to load-library bookmark+-mac.  Require it only if cannot load-library.
+;; 2012/06/15 dadams
+;;     bookmark-bmenu-mode, bmkp-bmenu-mode-status-help: Improved doc string.
+;;     bmkp-bmenu-show-or-edit-annotation: Corrected doc string: bookmark, not buffer.
+;; 2012/06/14 dadams
+;;     Added face bmkp-no-local.
+;;     Redefined defaults for faces bmkp-non-file and bmkp-variable-list.
+;;     bmkp-bmenu-mode-status-help: Added legend for no such local file.
+;;     bmkp-bmenu-propertize-item: Distinguish no such local file from no such existing buffer.
+;; 2012/06/13 dadams
+;;     bookmark-bmenu-bookmark: forward-char bmkp-bmenu-marks-width, not 1+ that.
+;;     bmkp-bmenu-propertize-item: Allow a file bookmark to get buffer prop if file not yet saved.
+;;                                 Do not require buffer-name attribute for bmkp-non-file face.
+;; 2012/06/11 dadams
+;;     bmkp-bmenu-propertize-item: Use bmkp-non-file-filename also if filename is missing from bmk.
+;; 2012/05/05 dadams
+;;     bookmark-bmenu-(un)mark(-all), bmkp-bmenu-regexp-mark, bmkp-bmenu-toggle-marks,
+;;       bmkp-bmenu-mark-bookmarks-satisfying, bmkp-bmenu-toggle-marked-temporary/savable,
+;;       bmkp-bmenu-(un)mark-bookmarks-tagged-regexp:
+;;         Added optional arg MSG-P.
+;;     bookmark-bmenu-(un)mark(-all), bookmark-bmenu-execute-deletions, bmkp-bmenu-regexp-mark,
+;;       bmkp-bmenu-toggle-show-only-(un)marked, bmkp-bmenu-mark-bookmarks-satisfying,
+;;       bmkp-bmenu-toggle-marks, bmkp-bmenu-toggle-marked-temporary/savable,
+;;       bmkp-bmenu-toggle-temporary, bmkp-bmenu-make-sequence-from-marked,
+;;       bmkp-bmenu-(un)omit(-marked), bmkp-bmenu-(un)mark-bookmarks-tagged-regexp,
+;;       bmkp-bmenu-mark/unmark-bookmarks-tagged-*, bmkp-bmenu-change-sort-order,
+;;       bmkp-reverse(-multi)-sort-order:
+;;         Pass NO-MSG-P to *-refresh/rebuild-menu-list, *-surreptitiously-rebuild-list, *-store.
+;;     bmkp-bmenu-mark/unmark-bookmarks-tagged-(all/none|some/not-all):
+;;       Swapped last two args, so consistent order.
+;;     bmkp-bmenu-(un)mark-bookmarks-tagged-*: Updated arg order in calls to b-b-m/u-b-t-(a/n|s/n-a).
+;;     bmkp-bmenu-(un)mark-bookmarks-tagged-regexp, bmkp-bmenu-mark/unmark-bookmarks-tagged-*:
+;;       Added status message.
+;; 2012/05/01 dadams
+;;     Added redefinition of bookmark-bmenu-delete-backwards (they broke its movement).
+;;     Added aliases: bmkp-bmenu-flag-for-deletion(-backwards).  Bind to d, k, C-d (same as aliases).
+;;     bmkp-bmenu-(add|remove)-tags, bmkp-bmenu-(add|remove)-tags-(to|from)-marked:
+;;         Automatically re-sort if # tagged bmks changed and sort order is tagged first/last (s t).
+;;     Added: bmkp-bmenu-sort-tagged-before-untagged.
+;;     Bind bmkp-bmenu-sort-tagged-before-untagged to s t.
+;;     Bind bmkp-bmenu-sort-by-last-bookmark-access to s d, not s t.
+;;     Bind bmkp-bmenu-sort-by-last-local-file-access to s f d, not s f t.
+;;     Bind bmkp-bmenu-sort-by-local-file-type to s f k, not s f d.
+;; 2012/04/28 dadams
+;;     bookmark-bmenu-(un)mark(-all), bmkp-bmenu-regexp-mark, bmkp-bmenu-mark-bookmarks-satisfying,
+;;       bmkp-bmenu-toggle-marks, bmkp-bmenu-(un)mark-bookmarks-tagged-regexp,
+;;       bmkp-bmenu-mark/unmark-bookmarks-tagged-(all/none|some/not-all):
+;;         Added optional arg NO-RE-SORT-P.
+;;         Automatically re-sort if marks changed and if sort order is marked first/last (s >).
+;;     Changed all non-interactive calls of bookmark-bmenu-(un)mark to pass non-nil NO-RE-SORT-P.
+;;     bmkp-bmenu-toggle-marks: Call bookmark-bmenu-ensure-position at start.
+;; 2012/04/27 dadams
+;;     bmkp-bmenu-edit-marked: Use bmkp-with-output-to-plain-temp-buffer.
+;; 2012/04/13 dadams
+;;     Added: bmkp-bmenu-sort-(flagged|modified)-before-un(flagged|modified), bmkp-flagged-bookmarks.
+;;     Bound bmkp-bmenu-sort-(flagged|modified)-before-un(flagged|modified) to s D, s *.
+;;     bookmark-bmenu-(un)mark: Delete bookmark from bmkp-flagged-bookmarks.
+;;     bookmark-bmenu-mark: Use (equivalent of) eq version of add-to-list.
+;;     bookmark-bmenu-delete: Add bookmark to bmkp-flagged-bookmarks.
+;;     bmkp-bmenu-list-1: Always reset bmkp-(flagged|modified)-bookmarks.
+;;                        Flag bookmarks if bmkp-flagged-bookmark-p.
+;;     bmkp-bmenu-refresh-menu-list: C-u resets bmkp-flagged-bookmarks too.
+;; 2012/04/10 dadams
+;;     bmkp-bmenu-load-marked-bookmark-file-bookmarks:
+;;       Use bmkp-refresh-menu-list, not bmkp-refresh/rebuild-menu-list.
+;;     bmkp-bmenu-(add|remove)-tags-(to|from)-marked, bmkp-bmenu-paste-(add|replace)-tags-to-marked:
+;;       Corrected bookmark-save to bookmark-save-flag in bindings to nil.
+;;       Use bmkp-count-multi-mods-as-one-flag for the binding.
+;;       Call bmkp-refresh-menu-list.
+;; 2012/04/09 dadams
+;;     bmkp-bmenu-set-tag-value, bmkp-bmenu-remove-tags, bmkp-bmenu-paste-(add|replace)-tags:
+;;       Added nil NO-UPDATE-P arg in calls to bmkp-set-tag-value, bmkp-remove-tags,
+;;       bmkp-paste-(add|replace)-tags.
+;;     bmkp-bmenu-add-tags-to-marked, bmkp-bmenu-remove-tags-from-marked,
+;;       bmkp-bmenu-paste-(add|replace)-tags-to-marked:
+;;         Bind bookmark-save to nil around iteration, to inhibit saving until finished.
+;;         New arg order for calls to bmkp-(add|remove)-tags.
+;;         Pass non-nil NO-UPDATE-P arg to bmkp-paste-(add|replace)-tags.
+;; 2012/04/03 dadams
+;;     Moved here from bookmark+-1.el: bmkp-face-prop.
+;; 2012/03/19 dadams
+;;     Added: bmkp-*-mark.
+;;     bmkp-bmenu-list-1, bmkp-bmenu-mode-status-help: Use bmkp-*-mark for *.
+;; 2012/03/18 dadams
+;;     bookmark-bmenu-delete: Remove bookmark from bmkp-modified-bookmarks also.
+;;     bmkp-bmenu-list-1: RESET-P resets bmkp-modified-bookmarks also.  Insert modified marks (*).
+;;     bmkp-bmenu-refresh-menu-list:
+;;       When revert from file: Reset *-marked-bookmarks, *-modified-bookmarks, *-omitted-bookmarks.
+;;                              Bind bmkp-bmenu-filter-function to nil for bmkp-refresh-menu-list.
+;;     bmkp-bmenu-toggle-show-only-(un)marked:
+;;       Save display, so bmkp-bmenu-before-hide-marked-alist is up-to-date.
+;;     bmkp-bmenu-mode-status-help: Added legend for markings.
+;;     bmkp-bmenu-edit-marked: Use (shallow) copies of bookmarks, not originals.
+;;     Added bmkp-save-menu-list-state to Bookmark+ menu.
+;; 2012/03/13 dadams
+;;     bmkp-bmenu-read-filter-input:
+;;       If C-g then restore previous display.
+;;       Use only one catch and test while condition.
+;;       Do not try to pop an empty list.
+;;     bmkp-bmenu-filter-((bookmark|file)-name|annotation|tags)-incrementally:
+;;       Use run-with-idle-timer, not run-with-timer
+;; 2012/03/11 dadams
+;;     Added Revert to Saved (bmkp-revert-bookmark-file) to menu.
+;; 2012/03/07 dadams
+;;     bmkp-bmenu-load-marked-bookmark-file-bookmarks: Use bmkp-sorted-alist to load in display order.
+;; 2012/03/06 dadams
+;;     bookmark-bmenu-mode: Reorg.
+;;     bmkp-bmenu-refresh-menu-list:
+;;       Call bmkp-refresh-menu-list also when revert file.  Use yes-or-no-p, not y-or-n-p.
+;; 2012/03/05 dadams
+;;     bmkp-bmenu-mode-status-help: Added Autosave bookmarks and Autosave list display to info at top.
+;; 2012/03/04 dadams
+;;     Added: bmkp-bmenu-load-marked-bookmark-file-bookmarks.
+;;     Bind bmkp-toggle-saving-menu-list-state to C-M-~, not M-l.
+;;     Bind bmkp-bmenu-load-marked-bookmark-file-bookmarks to M-l.  Add it to menu.
+;; 2012/03/02 dadams
+;;     bookmark-bmenu-list: Reset marked and omitted lists to () if a name is not a current bmk.
+;; 2012/02/28 dadams
+;;     Added face bmkp-file-handler.
+;;     bmkp-bmenu-mode-status-help: Added bmkp-file-handler to face legend.
+;;     bmkp-bmenu-propertize-item: Propertize file-handler bookmarks, with bmkp-file-handler.
+;; 2011/12/31 dadams
+;;     Define macro with-buffer-modified-unmodified for Emacs 23.1, in addition to Emacs < 23.
+;; 2011/12/30 dadams
+;;     Added aliases: bmkp-bookmark-(data|name)-from-record.
+;;     Added: bmkp-bmenu-show-or-edit-annotation, bmkp-bmenu-edit-bookmark-record,
+;;            bmkp-bmenu-edit-marked.
+;;     Renamed bmkp-bmenu-edit-bookmark to bmkp-bmenu-edit-bookmark-name-and-file.
+;;     bookmark-bmenu-mark: Propertize bookmark name with bmkp-full-record before adding to list.
+;;     bookmark-bmenu-list:
+;;       Added optional arg MSGP.  Show status messages.
+;;       Propertize bookmark names if not already propertized, in marked and omitted lists.
+;;     bookmark-bmenu-mode: Updated doc string.
+;;     bmkp-bmenu-make-sequence-from-marked:
+;;       Use bmkp-get-bookmark-in-alist, not bookmark-get-bookmark.
+;;     Bind bmkp-bmenu-show-or-edit-annotation (not *-show-annotation) to a.
+;;     Bind bmkp-bmenu-edit-bookmark-name-and-file to r now, not E.
+;;     Bind bmkp-bmenu-edit-marked to E and T > e.
+;;     Bind bmkp-bmenu-edit-bookmark-record to e.
+;;     bmkp-bmenu-quit: Show progress messages.
+;;     bmkp-bmenu-tags-menu: Added bmkp-bmenu-edit-marked.
+;;     bmkp-bmenu-mouse-3-menu:
+;;       Added: bmkp-bmenu-edit-tags.
+;;       Replaced *-rename and *-relocate with bmkp-bmenu-edit-bookmark-name-and-file.
+;; 2011/12/24 dadams
+;;     Added: bookmark-bmenu-toggle-filenames, with optional arg NO-MSG-P.
+;;     bookmark-bmenu-surreptitiously-rebuild-list, bookmark-bmenu-(show|hide)-filenames:
+;;       Added progress messages and optional arg NO-MSG-P.
+;;     bookmark-bmenu-(show|hide)-filenames, bookmark-bmenu-toggle-filenames:
+;;       Correct FORCE behavior and doc strings.
+;;     bmkp-bmenu-refresh-menu-list: Pass (not) MSG-P to bmkp-refresh-menu-list.
+;; 2011/12/21 dadams
+;;     Added: bmkp-bmenu-mark-orphaned-local-file-bookmarks,
+;;            bmkp-bmenu-show-only-orphaned-local-files, bmkp-bmenu-mark-variable-list-bookmarks.
+;;     bmkp-bmenu-refresh-menu-list: Added optional args ARG and MSGP, so you can revert from file.
+;;     bookmark-bmenu-mode: Updated and reordered doc string.
+;;     Bind O M, O S to orphaned commands, not omit commands.  Changed omit bindings to use -, not O.
+;;     Bind bmkp-bmenu-mark-variable-list-bookmarks to V M.
+;;     bmkp-bmenu-show-menu: Reordered.  Added: *-w3m-urls, *-variable-lists, *-orphaned-local-files.
+;;     bmkp-bmenu-mark-menu: Reordered.  Added: *-w3m-*, *-variable-list-*, *-orphaned-local-file-*.
+;; 2011/12/19 dadams
+;;     Added: with-buffer-modified-unmodified.
+;;     bookmark-bmenu-((un)mark|delete), bookmark-bmenu-(show|hide)-filenames:
+;;       Use with-buffer-modified-unmodified.
+;;     bookmark-bmenu-show-filenames, bmkp-bmenu-mouse-3-menu: Use line-(beginning|end)-position.
+;; 2011/12/15 dadams
+;;     bmkp-bmenu-propertize-item: Use bmkp-local-directory face also for Dired (e.g. with wildcards).
+;;     bmkp-bmenu-mode-status-help: Clarify legend for remote and local dirs/Dired.
+;; 2011/12/08 dadams
+;;     bmkp-bmenu-mouse-3-menu: Use easymenu to build the menu.  Conditionalize some items.
+;;     Bind down-mouse-3, not mouse-3, to bmkp-bmenu-mouse-3-menu.  (bind mouse-3 to ignore).
+;;     Added eval-when-compile for easymenu.el.
+;; 2011/12/05 dadams
+;;     bmkp-bmenu-menubar-menu: Reordered items regarding bookmark files.
+;;     bmkp-bmenu-mode-status-help: Correct intro text, reorder, use marker for position TOP.
+;;     bookmark-bmenu-mode: Changed intro text slightly.
+;; 2011/12/03 dadams
+;;     bmkp-bmenu-list-1: Print current bookmark file at top of display.
+;;     Increased bmkp-bmenu-header-lines to 5.
+;;     bookmark-bmenu-mode: Updated doc string for binding changes and new option.
+;;     bmkp-bmenu-regexp-mark: Mention right-padding of bookmark names in doc string.
+;;     bmkp-bmenu-mode-status-help: Reorder Current Status items, to put bookmark file first.
+;;     Bind L to bmkp-switch-bookmark-file-create, not bmkp-switch-bookmark-file.
+;; 2011/11/19 dadams
+;;     bmkp-bmenu-image-bookmark-icon-file: Default to an existing Emacs image file, not nil.
+;; 2011/11/18 dadams
+;;     Added: bmkp-bmenu-mark-image-bookmarks, bmkp-bmenu-show-only-image-files,
+;;            bmkp-bmenu-image-bookmark-icon-file.
+;;     bmkp-bmenu-list-1: Show icon image for image-file bookmarks.
+;;     bookmark-bmenu-mode: Add to doc string: bmkp-image-jump, bmkp-bmenu-mark-image-bookmarks,
+;;                                             bmkp-bmenu-show-only-image-files.
+;;     bmkp-bmenu-mode-status-help: Added image icon to legend.
+;;     Bound keys: M-I M-M, M-I M-S to *-mark-image-bookmarks *-show-only-image-files.
+;;     Added to menus (Mark, Show): bmkp-bmenu-mark-image-bookmarks, bmkp-bmenu-show-only-image-files.
+;; 2011/11/01 dadams
+;;     bookmark-bmenu-mode: Changed mode-name var for mode line: Bookmarks, not Bookmark Menu.
+;;                          Updated doc string for autofile & temporary jump commands.
+;; 2011/10/31 dadams
+;;     bookmark-bmenu-mode: Updated doc string with bmkp-toggle-autotemp-on-set.
+;;     bmkp-bmenu-menubar-menu: Added: bmkp-toggle-autotemp-on-set.
+;; 2011/10/27 dadams
+;;     Added: bmkp-X-mark, bmkp-bmenu-toggle-marked-temporary/savable, bmkp-bmenu-toggle-temporary,
+;;            bmkp-bmenu-mark-autonamed-bookmarks, bmkp-bmenu-show-only-temporary,
+;;            bmkp-bmenu-mark-temporary-bookmarks.
+;;     bmkp-bmenu-list-1: Mark with X in place of a, if bookmark is temporary.
+;;     bookmark-bmenu-mode: Mode-line major-mode name indicates when in temporary bookmarking mode.
+;;                          Updated doc string with temporary bookmark commands.
+;;     bmkp-t-mark: Changed default attributes.
+;;     Bind: M-L to bmkp-temporary-bookmarking-mode, M-X to bmkp-bmenu-toggle-marked-temporary/savable
+;;           X M to bmkp-bmenu-mark-temporary-bookmarks, X S to bmkp-bmenu-show-only-temporary,
+;;           C-M-X to bmkp-bmenu-toggle-temporary.
+;;     bmkp-bmenu-show-only-bookmark-files: Bind to Y S, not X S.
+;;     bmkp-bmenu-mark-bookmark-file-bookmarks: Bind to Y M, not X M.
+;; 2011/07/01 dadams
+;;     bmkp-bmenu-change-sort-order, bmkp(-multi)-reverse-sort-order: Handle null CURRENT-BMK.
+;; 2011/04/24 dadams
+;;     Added to Tags menu: Purge Autofiles with No Tags.
+;; 2011/04/23 dadams
+;;     Bound bmkp-bmenu-set-tag-value-for-marked to T > v and added to bmkp-bmenu-tags-menu.
+;;     bmkp-bmenu-mouse-3-menu: Added bmkp-rename-tag.
+;; 2011/04/22 dadams
+;;     Bound *-copy-tags to T c, T M-w, *-paste(-add|replace)-tags to T p, T C-y, T q.
+;; 2011/04/21 dadams
+;;     Added:  bmkp-bmenu-copy-tags, bmkp-bmenu-paste-add-tags(-to-marked),
+;;             bmkp-bmenu-paste-replace-tags(-for-marked).
+;;     Bound and added to menus: bmkp-bmenu-paste-add-tags-to-marked,
+;;                               bmkp-bmenu-paste-replace-tags-for-marked.
+;;     Added to This Bookmark menu: bmkp-bmenu-copy-tags, bmkp-bmenu-paste(-add|replace)-tags.
+;; 2011/04/19 dadams
+;;     Added: bmkp-bmenu-unmark-bookmarks-tagged-regexp.  Bound it to T u %.  Added it to menu.
+;; 2011/04/16 dadams
+;;     Added: bmkp-edit-tags-send.  Bound it to T e in bookmark-bmenu-mode-map.
+;;     bookmark-bmenu-mode: Updated help text for tags editing.
+;;     bmkp-maybe-unpropertize-bookmark-names:
+;;       Test emacs-major-version, not just (boundp 'print-circle).
+;; 2011/04/15 dadams
+;;     Added: bmkp-bmenu-mark-autofile-bookmarks, bmkp-bmenu-show-only-autofiles.
+;;       And added them to menus.
+;;     bookmark-bmenu-mode-map:
+;;       Bind bmkp-bmenu-mark-autofile-bookmarks, bmkp-bmenu-show-only-autofiles to A M, A S.
+;;       Bind bookmark-bmenu-show-all-annotations to M-a, not A.
+;;       Bind bmkp-bmenu-search-marked-bookmarks-regexp to M-s a M-s, not M-a.
+;;       Bind *-mark-url-bookmarks, *-show-only-urls to M-u M-m, M-u M-s, not M-u M, M-u S.
+;;     bookmark-bmenu-mode: Updated help to reflect latest bindings.
+;; 2011/04/13 dadams
+;;     bmkp-bmenu-tags-menu: Added: bmkp-(un)tag-a-file.
+;; 2011/04/12
+;;     Added: bmkp-propertize-bookmark-names-flag, bmkp-maybe-unpropertize-bookmark-names,
+;;            bmkp-bmenu-get-marked-files.
+;;     Renamed: bmkp-bmenu-omitted-list to bmkp-bmenu-omitted-bookmarks.
+;;     bmkp-bmenu-define-full-snapshot-command:
+;;       Bind print-circle to t around pp.  Use bmkp-maybe-unpropertize-bookmark-names on lists.
+;;     bookmark-bmenu-(show|hide)-filenames, bmkp-bmenu-toggle-show-only-(un)marked,
+;;       bmkp-bmenu-(un)omit-marked:
+;;         Fit one-window frame only if selected window is *Bookmark List*.
+;;     bookmark-bmenu-bookmark: Added optional arg FULL.  Non-nil means return full bookmark record.
+;;     bookmark-bmenu-unmark, bookmark-bmenu-delete, bmkp-bmenu-unomit-marked:
+;;       Use bmkp-delete-bookmark-name-from-list, not delete.
+;;     bookmark-bmenu-execute-deletions: Pass full bookmark, not name, to delete, and don't use assoc.
+;;     bookmark-bmenu-rename: Use bmkp-bmenu-goto-bookmark-named instead of just searching for name.
+;;     bmkp-bmenu-toggle-marks, bmkp-bmenu-unomit-marked, bmkp-bmenu-define-jump-marked-command,
+;;       bmkp-bmenu-mouse-3-menu:
+;;         Use bmkp-bookmark-name-member, not member.
+;;     bmkp-bmenu-make-sequence-from-marked: Do not invoke bookmark-bmenu-list when no displayed list.
+;;     bmkp-bmenu-define-command: Use bmkp-maybe-unpropertize-bookmark-names on *-omitted-bookmarks.
+;;     bmkp-bmenu-list-1: Use bmkp-sort-omit, not bmkp-sort-and-remove-dups.
+;;                        Pass full bookmark to bmkp-bmenu-propertize-item.
+;;     bmkp-bmenu-propertize-item:
+;;       First arg is now a full bookmark, not a bookmark name.  Get bookmark name from it.
+;;       Put prop bmkp-bookmark-name on buffer text with propertized bookmark-name string as value.
+;;       String has property bmkp-full-record with value the full bookmark record, with string as car.
+;;       Return propertized bookmark-name string.
+;;     bmkp-bmenu-isearch-marked-bookmarks(-regexp), bmkp-bmenu-dired-marked,
+;;       bmkp-bmenu-(search|query-replace)-marked-bookmarks-regexp:
+;;         Use bmkp-sort-omit, not bmkp-sort-and-remove-dups.
+;;     bmkp-bmenu-goto-bookmark-named:
+;;       If NAME has property bmkp-full-record then go to the bookmark it indicates.  Otherwise, just
+;;       go to the first bookmark with the same name.
+;;     bookmark-bmenu-mode: Added bmkp-save-menu-list-state (now a command) to the mode help.
+;; 2011/04/02 dadams
+;;     bookmark-bmenu-mode: Added to mode help: bmkp-file-this-dir-(all|some)-tags(-regexp)-jump.,
+;;                                              Create/Set section, with bmkp-autofile-set.
+;; 2011/04/01 dadams
+;;     bookmark-bmenu-mode: Added to mode help: bmkp-(dired|file)-this-dir-jump.
+;; 2011/03/26 dadams
+;;     bookmark-bmenu-mode: Added new file-with-tags jump commands to the help.
+;; 2011/03/05 dadams
+;;     bmkp-bmenu-edit-bookmark: Use bmkp-refresh-menu-list, not *-surreptitiously-rebuild-list.
+;; 2011/02/11 dadams
+;;     Faces: Better defaults for dark background.
+;; 2011/01/03 dadams
+;;     Removed autoload cookies from non def* sexps and from define-key.
+;;     Added missing autoload cookies for commands, in particular redefined std commands & defalias.
+;; 2010/12/10 dadams
+;;     Added defalias for bookmark-name-from(-full)-record, to fix gratuitous Emacs name change.
+;; 2010/09/24 dadams
+;;     Added: bmkp-bmenu-show-only-autonamed.  Bound to # S.  Added to bmkp-bmenu-show-menu.
+;;     bookmark-bmenu-mode: Updated doc string for autonamed jumps, show.
+;;     Renamed varlist to variable-list everywhere.
+;; 2010/08/22 dadams
+;;     Added: bmkp-bmenu-filter-annotation-incrementally, bookmark-bmenu-relocate (Emacs 20, 21),
+;;            bmkp-bmenu-filter-alist-by-annotation-regexp.  Bound, added to menus and help.
+;; 2010/08/18 dadams
+;;     Removed eval-when-compile for bookmark+-(lit|1).el.
+;;     bmkp-bmenu-propertize-item: Inconsequential simplification.
+;; 2010/08/17 dadams
+;;     bmkp-bmenu-edit-bookmark: Added optional arg INTERNALP (prefix arg), for editing record.
+;; 2010/08/15 dadams
+;;     Moved to bookmark+-mac.el:
+;;       bmkp-define-sort-command, bmkp-replace-regexp-in-string, bmkp-assoc-delete-all.
+;;     Renamed: bmkp-barf-if-not-in-menu-list to bmkp-bmenu-barf-if-not-in-menu-list.
+;;     Require bookmark.el, bookmark+-mac.el.
+;;     Require when compile: bookmark+-1.el, bookmark+-lit.el (soft).
+;; 2010/07/17 dadams
+;;     Added: bmkp-bmenu-mark-url-bookmarks, bmkp-bmenu-show-only-urls, bmkp-bmenu-sort-by-url.
+;;     Removed: bmkp-bmenu-sort-by-w3m-url.
+;;     Replaced face bmkp-w3m by bmkp-url.
+;;     bookmark-bmenu-mode: Added mark and show URL commands.
+;;     bookmark-bmenu-mode, *-status-help, *-sort-by-bookmark-type, *-define-sort-command: w3m -> url.
+;;     Bind bmkp-bmenu-sort-by-url, not bmkp-bmenu-sort-by-w3m-url.
+;;     Bind bmkp-bmenu-mark-url-bookmarks, bmkp-bmenu-show-only-urls.
+;;     Replace W3M by URL in menu items.
+;; 2010/07/14 dadams
+;;     Created from bookmark+.el code.
+ 
+;;;(@* "CHANGE LOG FOR `bookmark+-doc.el'")
+;;
+;; 2020/07/04 dadams
+;;     Changed all references to `C-x p' to `C-x x'.
+ 
+;;;(@* "CHANGE LOG FOR `bookmark+-key.el'")
+;;
+;; 2021/09/19 dadams
+;;     Everywhere: Use bmkp-bmenu-buffer, not vanilla bookmark-bmenu-buffer.
+;; 2021/02/12 dadams
+;;     Typo in eval-after-load for EWW: previous -> next.
+;; 2020/07/04 dadams
+;;     Changed all `C-x p' to `C-x x'.
+;;     Replaced string *Bookmark List* with bookmark-bmenu-buffer (for Emacs 28).
+;; 2020/06/20 dadams
+;;     Correctly added bmkp-compilation-target-set(-all) to compilation and grep maps.
+;; 2020/01/27 dadams
+;;     Bind bookmark-jump-other-frame to 5 in bookmark-map.
+;; 2020/01/25 dadams
+;;     bmkp-bookmarks-here-menu-command-entries:
+;;       Added bmkp-edit-bookmark-record-file/buffer, bmkp-set-lighting-for-this-buffer,
+;;             bmkp-unlight-this-buffer, bmkp-(un)light-(non-)autonamed-this-buffer
+;;       Use bmkp-light-this-buffer, not bmkp-light-bookmarks.
+;;       menu-bar-bookmark-map > bmkp-here-menu: Rename; use bmkp-exists-this-file/buffer-bookmarks-p.
+;; 2020/01/24 dadams
+;;     Added: bmkp-annotate-map, bmkp-annotate-menu.
+;;     bmkp-bookmarks-here-menu-command-entries, bmkp-highlight-menu:
+;;       Added: bmkp-describe-bookmark-lighted-here.
+;;     bmkp-bookmarks-here-menu-command-entries:
+;;       Added: bmkp-light-bookmarks, bmkp-bookmarks-lighted-at-point,
+;;              bmkp-annotate-bookmark-this-file/buffer, bmkp-annotate-all-bookmarks-this-file/buffer.
+;;     Bind annotation commands to prefix C-x p a (bmkp-annotate-map).
+;;     Move Here submenu before Highlight submenu.
+;;     Typo in name when binding: bmkp-this-file/buffer-bmenu-list.
+;; 2020/01/22 dadams
+;;     Bind bmkp-switch-to-bookmark-file-this-file/buffer to C-x p C-l,
+;;          bmkp-save-bookmarks-this-file/buffer to C-x p C-s.
+;;     Change bmkp-jump-to-list from C-x [pj] C-l to C-x [pj] C-j.
+;;     bmkp-bookmarks-here-menu-command-entries:
+;;       Added bmkp-(switch-to-bookmark-file|save-bookmarks)-this-file/buffer.
+;; 2019/08/13 dadams
+;;     Bind bmkp-clone-bookmark to C-x p 2.
+;;     menu-bar-bookmark-map: Add bmkp-clone-bookmark.
+;; 2019/05/16 dadams
+;;     Added: bmkp-add-bookmarks-here-menu-flag, bmkp-here-menu, bmkp-exists-bookmark-satisfying-p,
+;;            bmkp-exists-this-file/buffer-bookmarks-p, bmkp-bookmarks-here-menu-command-entries,
+;;     Add bmkp-here-menu to menu-bar-bookmark-map, Buffer-menu-mode-map, Info-mode-menu,
+;;         diredp-bookmark-menu or dired-mode-map.
+;;     Add bmkp-dired-this-dir-jump to diredp-bookmark-menu or dired-mode-map.
+;; 2019/05/01 dadams
+;;     Bind bmkp-jump-to-list to C-x p C-l, C-x j C-l.
+;; 2019/04/22 dadams
+;;     Bind bmkp-describe-bookmark to C-h M, bmkp-describe-bookmark-lighted-here to C-x p ?.
+;; 2018/10/10 dadams
+;;     Bound bookmark-jump-other-frame to C-x 5 B, C-x j 5 globally, and J 5 in bookmark-list buffer.
+;; 2017/10/14 dadams
+;;     All EWW stuff is for Emacs 25+, not Emacs 24.4+.
+;; 2017/01/10 dadams
+;;     Applied renaming: bmkp-replace-eww-keys-flag to bmkp-eww-replace-keys-flag.
+;; 2017/01/02 dadams
+;;     menu-bar-bookmark-map: Added menu item Store Org Link To....
+;;     Typo: bmkp-replace-EWW-keys-flag -> bmkp-replace-eww-keys-flag.
+;; 2016/12/11 dadams
+;;     Remap EWW keys to bmkp- keys.
+;; 2016/11/23 dadams
+;;     Put :advertised-binding on several keys.
+;; 2016/11/15 dadams
+;;     bmkp-eww-jump(-other-window): Ensure that EWW code is only for Emacs 25+.
+;; 2016/11/14 dadams
+;;     Added bindings for bmkp-eww-jump(-other-window), including in eww-mode-map.
+;;     Bind bmkp-delete-bookmarks to kill-line keys (C-x p C-k, C-x p deleteline).
+;; 2016/06/24 dadams
+;;     Added bmkp-delete-bookmarks binding for <deletechar> and <kp-delete>.
+;; 2016/05/15 dadams
+;;     dired-mode-hook:
+;;       If diredp-bookmark-menu is defined then use that.
+;;       Rename menu item: Show This Dir Using a Bookmark -> Jump to a Dired Bookmark For This Dir.
+;; 2016/05/08 dadams
+;;     Added: bmkp-bookmark-map-prefix-key, bmkp-jump-map-prefix-key,
+;;            bmkp-jump-other-window-map-prefix-key, bmkp-set-map-prefix-key.
+;;     Removed hard-coded bindings for keymaps in ctl-x-map, ctl-x-4-map.
+;;     (eval-when-compile (require 'cl)) ;; case
+;; 2015/01/04 dadams
+;;     Bind bmkp-region-jump-narrow-indirect-other-window to C-x 4 j R.
+;; 2014/07/11 dadams
+;;     bmkp-highlight-menu: Added item Toggle Autofile Highlighting in Dired.
+;; 2014/07/06 dadams
+;;     Removed: bmkp-options-menu.  Use bmkp-bmenu-toggle-menu, and rename Toggle, not Toggle Option.
+;;     Removed individual toggle commands from menu-bar-bookmark-map (Bookmarks).
+;;     Reuse bmkp-bmenu-toggle-menu for menu-bar-bookmark-map [options].
+;; 2014/07/05 dadams
+;;     Moved submenu bmkp-jump-tags-menu before individual menu items.
+;; 2014/03/23 dadams
+;;     Bind j and J in bookmark-bmenu-mode-map.  Bind also j > there.
+;;     Add bmkp-bmenu-jump-to-marked to bmkp-jump-menu when in bookmark-list display.
+;; 2013/10/29 dadams
+;;     Bind bookmark-set's previous keys to bmkp-bookmark-set-confirm-overwrite.
+;;     Bind bookmark-set to C-x r M, not C-x r m.
+;;     bmkp-menu-bar-set-bookmark: Use bmkp-bookmark-set-confirm-overwrite, not bookmark-set.
+;; 2013/07/20 dadams
+;;     Moved items to new submenus: New/Update and Delete.
+;; 2013/06/30 dadams
+;;     Bind bmkp-set-snippet-bookmark to C-x p M-w, bmkp-snippet-to-kill-ring to C-x j M-w.
+;; 2013/05/28 dadams
+;;     Applied renaming of bmkp-edit-bookmark-name-and-file to bmkp-edit-bookmark-name-and-location.
+;; 2013/04/15 dadams
+;;     In bmkp-set-map: Bind F to bmkp-make-function-bookmark (C-x p c F).
+;;                      Bind C-k to bmkp-wrap-bookmark-with-last-kbd-macro (C-x p c C-k).
+;;                      Bind s to bmkp-set-sequence (C-x p c s).
+;; 2012/08/31 dadams
+;;     Do not bind bmkp-compilation-target-set(-all) unless defined.
+;; 2012/06/26 dadams
+;;     Wrapped require of bookmark+-mac.el in eval-when-compile.
+;; 2012/06/21 dadams
+;;     Try to load-library bookmark+-mac, for bmkp-menu-bar-make-toggle.
+;; 2012/02/26 dadams
+;;     Bind:
+;;       bmkp-this-file/buffer-bmenu-list to C-x p , not C-x p ..
+;;       bmkp-(file|dired)-this-dir-jump* to C-x j . f|d not C-x j C-f|C-d.
+;;       bmkp-file-this-dir-*-tags(-regexp)-jump* to C-x j t . [%][*+] not C-x j t C-f [%][*+].
+;;       bmkp-this-buffer-jump* to C-x j , , not C-x j ..
+;;       bmkp-autonamed-this-buffer-jump* to C-x j , # not C-x j # ..
+;;       bmkp-autonamed-jump* to C-x j # not C-x j # #.
+;;       bmkp-autofile-jump* in all Emacs versions.
+;;       bmkp-find-file(-other-window), which is new, to C-x j C-f.
+;;       new autofile tags jump commands bmkp-autofile-(all|some)-tags(-regexp)-jump* to
+;;         C-x j t a [%][*+], which was for bmkp-find-file-*-tags*.
+;;       bmkp-find-file-(all|some)-tags(-regexp)* to C-x j t C-f [%] [*+] not C-x j t a [%] [*+].
+;;     Add to menus: bmkp-autofile-*.  Rename menu items for bmkp-find-file: Find Autofile....
+;;     Rename menu Bookmarked File to Find File or Autofile.  For Emacs 20-21, make it a single item.
+;;     bmkp-jump-tags-menu, bmkp-find-file-menu: Do not add Autofile tags items for Emacs 20.
+;; 2012/02/21 dadams
+;;     Added bindings for: bmkp-autofile-(all|some)-tags(-regexp)-jump(-other-window),
+;;                         bmkp-find-file(-other-window) (was same as *autofile*).
+;;     Changed bindings:
+;;       *-this-dir*: . [df] (was C-d/C-f), *this-buffer*: , (was .), *find-file*tags*: C-f (was a).
+;;     Define *autofile* for all Emacs versions.  Separate bindings from *find-file* cmds.
+;; 2011/12/30 dadams
+;;     Added aliases: bmkp-bookmark-(data|name)-from-record.
+;;     Bind E to bmkp-edit-bookmark-record, not bmkp-edit-bookmark.
+;;     Bind r to bmkp-edit-bookmark-name-and-file, not bookmark-rename.  Ditto in menu.
+;;     Use bmkp-get-bookmark-in-alist, not bookmark-get-bookmark in :visible conditions.
+;;     menu-bar-bookmark-map: Added bmkp-edit-bookmark-record.
+;;     bmkp-tags-menu: Added bmkp-edit-tags.
+;; 2011/12/14 dadams
+;;     Removed conditions :enable bookmark-alist.
+;; 2011/12/09 dadams
+;;     Commented out menu items with complex :enable conditions, replacing them with simple ones.
+;;       Reason: too slow, especially in Emacs 20.
+;; 2011/12/05 dadams
+;;     menu-bar-bookmark-map: Reordered items regarding bookmark files.
+;; 2011/12/03 dadams
+;;     Bind C-x p L to bmkp-switch-bookmark-file-create, not bmkp-switch-bookmark-file.
+;;     Reordered bookmark-file items in menu-bar-bookmark-map.
+;; 2011/11/18 dadams
+;;     Bind bmkp-image-jump(-other-window) to C-x (4) j M-i.
+;;     bmkp-jump-menu: Add bmkp-image-jump-other-window.
+;; 2011/11/15 dadams
+;;     Bind *-this-file/buffer*, not *-this-buffer*.
+;; 2011/11/01 dadams
+;;     Bind alias bmkp-autofile-jump(-*), not bmkp-find-file(-*) to C-x j a, so Icicles picks up key.
+;;     Bind bmkp-bookmark-file-jump to C-x j y, not C-x j x.  Bind bmkp-temporary-jump(-*) to C-x j x.
+;;     bmkp-jump-menu: Bind bmkp-(autofile|temporary)-jump-other-window.
+;; 2011/10/31 dadams
+;;     Bind bmkp-toggle-autotemp-on-set to C-x p x.  Move bmkp-set-bookmark-file-bookmark to C-x p y.
+;;     menu-bar-bookmark-map: Added: bmkp-toggle-autotemp-on-set.
+;; 2011/10/28 dadams
+;;     menu-bar-bookmark-map:
+;;       Added: bmkp-delete-all-temporary-bookmarks, bmkp-temporary-bookmarking-mode.  Reordered.
+;;     bmkp-options-menu: Added: bmkp-toggle-saving-menu-list-state, bmkp-toggle-saving-bookmark-file.
+;; 2011/04/24 dadams
+;;     Added to Bookmarks menu and its Tags submenu: Purge Autofiles with No Tags.
+;; 2011/04/23 dadams
+;;     bmkp-tags-menu:
+;;       Added bmkp-set-tag-value, bmkp-(add|remove|copy)-tags, bmkp-paste-(add|replace)-tags.
+;; 2011/04/21 dadams
+;;     Bound: bmkp-copy-tags, bmkp-paste-add-tags, bmkp-paste-replace-tags.
+;; 2011/04/16 dadams
+;;     Added: bmkp-tags-map.  Bound tag commands to prefix C-x p t.
+;; 2011/04/14 dadams
+;;     Renamed menu Jump To Bookmark to just Jump To, in menu-bar-bookmark-map.
+;; 2011/04/13 dadams
+;;     Added:
+;;       bmkp-find-file-menu (bmkp-find-file(-(all|some)-tags(-regexp)(-other-window)),
+;;       bmkp-jump-tags-menu (what was in main, plus bmkp-find-file-*-tags-regexp*),
+;;       bmkp-tags-menu (list all, rename, remove from all, (un)tag a file).
+;;     bmkp-jump(-other-window)-map:
+;;       Added bmkp-find-file(-other-window) to menu.
+;;       Bound keys for bmkp-find-file-(all|some)-tags(-regexp)(-other-window): C-x (4) j t a...
+;; 2011/04/02 dadams
+;;     Added bindings for (new) bmkp-autofile-set,
+;;                              bmkp-file-this-dir-(all|some)-tags(-regexp)-jump(-other-window).
+;; 2011/04/01 dadams
+;;     Added to bmkp-jump-menu: bmkp-(dired|file)-this-dir-jump-other-window.
+;;     Created from code in bookmark+-1.el.
+ 
+;;;(@* "CHANGE LOG FOR `bookmark+-lit.el'")
+;;
+;; 2021/09/19 dadams
+;;     Everywhere: Use bmkp-bmenu-buffer, not vanilla bookmark-bmenu-buffer.
+;; 2021/04/16 dadams
+;;     bmkp-unlight-bookmark, bmkp-light-bookmarks, bmkp-cycle-lighted-this-buffer, bmkp-light-face,
+;;       bmkp-light-style, bmkp-light-when, bmkp-lighting-attribute, bmkp-overlay-of-bookmark:
+;;         Use bmkp-get-bookmark, not bookmark-get-bookmark, but in vanilla-compatible way.
+;;     bmkp-bookmarks-lighted-at-point, bmkp-light-bookmark, bmkp-a-bookmark-lighted-on-this-line:
+;;       Use bmkp-get-bookmark, not bookmark-get-bookmark.
+;; 2020/07/04 dadams
+;;     Replaced string *Bookmark List* with bookmark-bmenu-buffer (for Emacs 28).
+;; 2020/01/12 dadams
+;;     bmkp-lighted-jump-to-list: Raise error if no highlighted bookmarks at point.
+;;     bmkp-(un)light-bookmark-this-buffer: Pass non-nil USE-NIL-ALIST-P to bookmark-completing-read.
+;; 2019/08/21 dadams
+;;     bmkp-toggle-auto-light-when-(jump|set): Fix message: symbol-name, not symbol-value.
+;; 2019/05/01 dadams
+;;     Added bmkp-lighted-jump-to-list.
+;; 2019/04/23 dadams
+;;     Added bmkp-tooltip-content-function.
+;;     bmkp-make/move-overlay-of-style: Use bmkp-tooltip-content-function.
+;; 2019/04/22 dadams
+;;     Added bmkp-describe-bookmark-lighted-here.
+;;     bmkp-make/move-overlay-of-style: Put bookmark description on overlay help-echo property.
+;; 2018/09/21 dadams
+;;     Added: bmkp--pop-to-buffer-same-window.  (Added also to bookmark+-bmu.el.)
+;;     bmkp-lighted-jump: Use bmkp--pop-to-buffer-same-window, not switch-to-buffer.
+;; 2017/01/08 dadams
+;;     Use the term "entry", not "property" everywhere, for bookmark entries (fields).
+;; 2016/10/25 dadams
+;;     Added: Faces bmkp-light-autonamed-region, bmkp-light-non-autonamed-region.
+;;            Options bmkp-light-style-autonamed-region, bmkp-light-style-non-autonamed-region.
+;;     bmkp-light-styles-alist: Added Region style.
+;;     bmkp-make/move-overlay-of-style:
+;;       Added required arg BOOKMARK.  Put overlay on region if region bookmark.
+;;     bmkp-light-bookmark, bmkp-light-bookmarks:
+;;       Include newly added bookmark arg in calls to bmkp-make/move-overlay-of-style.
+;;     bmkp-light-face: Use face bmkp-light(-non)-autonamed-region for region bookmarks.
+;;     bmkp-light-style: Use style bmkp-light-style(-non)-autonamed-region for region bookmarks.
+;; 2016/09/10 dadams
+;;     bmkp-light-face, bmkp-light-style: Use bmkp-autonamed-bookmark-p.
+;; 2016/06/18 dadams
+;;     Protected use of fringe-bitmaps with boundp (should not be necessary though).
+;; 2015/04/02 dadams
+;;     eval-when-compile require of bookmark+-mac, for bmkp-define-show-only-command.
+;; 2015/02/08 dadams
+;;     Renamed: bmkp-bmenu-show-only-lighted to bmkp-bmenu-show-only-lighted-bookmarks.
+;;     bmkp-bmenu-show-only-lighted-bookmarks: Use macro bmkp-define-show-only-command to define it.
+;; 2014/07/06 dadams
+;;     Added: bmkp-last-auto-light-when-jump, bmkp-last-auto-light-when-set,
+;;            bmkp-toggle-auto-light-when-jump, bmkp-toggle-auto-light-when-set.
+;; 2013/06/09 dadams
+;;     Added vacuous defvars to suppress free-var warnings.
+;; 2013/05/15 dadams
+;;     Use bmkp-string-match-p instead of string-match wherever appropriate.
+;; 2012/10/09 dadams
+;;     Made all autoload cookies explicitly load bookmark+.el(c).  Should help ELPA (e.g. MELPA).
+;; 2012/09/22 dadams
+;;     bmkp-light-bookmark(s): Put full bookmark, not name, on overlay as its bookmark property.
+;;     bmkp-unlight-bookmark: Test using eq against full bookmark, not using equal against name.
+;;     bmkp-a-bookmark-lighted-at-pos: overlay-get now returns full bookmark, so get name if needed.
+;;     bmkp-overlay-of-bookmark: Use bookmark, not its name, like overlay-get does now.  Test with eq.
+;;     bmkp-light-bookmarks: Use add-to-list instead of unconditionally adding ov to ov-symb.
+;; 2012/04/28 dadams
+;;     bmkp-make/move-overlay-of-style, bmkp-make/move-fringe: Use FRONT-ADVANCE arg for make-overlay.
+;; 2011/12/30 dadams
+;;     Added aliases: bmkp-bookmark-(data|name)-from-record.
+;;     bmkp-bookmarks-lighted-at-point: Include only bookmarks in bookmark-alist.
+;;     bmkp-light-bookmark: Do nothing if BOOKMARK is not a bookmark or bookmark name.
+;;     bmkp-a-bookmark-lighted-at-pos: Return nil if no bookmark (at POS) in bookmark-alist.
+;; 2011/11/15 dadams
+;;     Applied renaming: bmkp-this-buffer-cycle-sort-comparer to *-this-file/buffer*.
+;; 2011/08/09 dadams
+;;     Bind icicle-unpropertize-completion-result-flag to t for all calls to completing-read.
+;; 2011/04/12
+;;     bmkp-cycle-lighted-this-buffer: Use bmkp-sort-omit, not bmkp-sort-and-remove-dups.
+;; 2011/04/01 dadams
+;;     bmkp-light-bookmark(s): Don't call bookmark-handle-bookmark.  Wrap with with-current-buffer.
+;; 2011/01/03 dadams
+;;     Added autoload cookies: defcustoms and commands.
+;; 2010/12/10 dadams
+;;     Added defalias for bookmark-name-from(-full)-record, to fix gratuitous Emacs name change.
+;; 2010/09/25 dadams
+;;     Added: bmkp-set-lighting-for(bookmarks|(-this)-buffer).  Requested by Joe Bloggs.
+;;     bmkp-set-lighting-for-bookmark: Added LIGHT-NOW-P arg (from prefix arg).
+;; 2010/09/11 dadams
+;;     Removed eval-when-compile for bookmark+-bmu, bookmark+-1.
+;; 2010/08/15 dadams
+;;     Require: bookmark.el.
+;;     Require when compile: bookmark+-bmu.el, bookmark+-1.el, pp+.el (soft).
+;;     Applied renaming of bmkp-barf-if-not-in-menu-list to bmkp-bmenu-barf-if-not-in-menu-list.
+;;     bmkp-light-bookmark(s): Added missing arg to throw call.
+;;     bmkp-light-bookmarks: Use bmkp-remove-if, not remove-if.
+;;     bmkp-light-bookmarks-in-region, bmkp-light-non-autonamed-this-buffer:
+;;       Use bmkp-remove-if-not, not remove-if-not.
+;;     bmkp-read-set-lighting-args: Use pp-read-expression-map only if bound (pp+.el).
+;; 2010/07/03 dadams
+;;     bmkp-set-lighting-for-bookmark, bmkp-bmenu-set-lighting-for-marked:
+;;       Use *-refresh-menu-list, not *-surreptitiously-*.
+;; 2010/07/01 dadams
+;;     Created.
+ 
+;;;(@* "CHANGE LOG FOR `bookmark+-mac.el'")
+;;
+;; **************************************************************************************************
+;; NOTE: If you byte-compile Bookmark+ (recommended), then WHENEVER `bookmark+-mac.el' is updated,
+;;       you      must load `bookmark+-mac.el' (not just `bookmark+-mac.elc'), then compile it, then
+;;       RECOMPILE *ALL* of the other Bookmark+ source files as well.  This is normal for Lisp: code
+;;       that depends on macros needs to be byte-compiled anew after loading the updated macros.
+;; **************************************************************************************************
+;;
+;; 2021/04/16 dadams
+;;     bmkp-define-file-sort-predicate: Use bmkp-get-bookmark, not bookmark-get-bookmark.
+;; 2021/03/04 dadams
+;;     Removed autoload cookie for bmkp-types-alist.  Its def is also in bookmark+-1.el now.
+;; 2020/11/28 dadams
+;;     Added: bmkp-define-history-variables, funtion bmkp-types-alist.
+;; 2017/03/31 dadams
+;;     bmkp-define-next+prev-cycle-commands: Added optional arg OTHERP.
+;; 2015/04/03 dadams
+;;     bmkp-replace-regexp-in-string: Copied defn here - used to produce the macro code for
+;;       bmkp-define-show-only-command and bmkp-define-sort-command.
+;; 2015/02/22 dadams
+;;     bmkp-menu-bar-make-toggle: Corrected doc string - just start with HELP.
+;; 2015/02/08 dadams
+;;     Added: bmkp-define-show-only-command.
+;; 2014/07/11 dadams
+;;     bmkp-define-sort-command: Use setq, not push, for Emacs 20.
+;; 2014/07/06 dadams
+;;     bmkp-menu-bar-make-toggle: Redefined - no longer use menu-bar-make-toggle.  Support keywords.
+;; 2014/05/27 dadams
+;;     Added: bmkp-with-help-window.
+;; 2013/04/26 dadams
+;;     Added: bmkp-with-bookmark-dir.  (Not used currently.  For user code.)
+;; 2012/10/09 dadams
+;;     Made all autoload cookies explicitly load bookmark+.el(c).  Should help ELPA (e.g. MELPA).
+;; 2012/06/26 dadams
+;;     Moved bmkp-assoc-delete-all, bmkp-replace-regexp-in-string to bookmark+-bmu.el.
+;; 2012/04/27
+;;     Added: bmkp-with-output-to-plain-temp-buffer.
+;; 2012/04/12 dadams
+;;     bmkp-define-sort-command: Do not bmkp-bmenu-goto-bookmark-named unless current-bmk (play safe).
+;; 2012/04/11 dadams
+;;     bmkp-define-sort-command: In function def, change order to: fn, reverse-fn, unsorted.
+;; 2011/12/30 dadams
+;;     bmkp-define-cycle-command: Applied renaming of bmkp-sort-and-remove-dups to bmkp-sort-omit.
+;;     bmkp-define-file-sort-predicate: Updated doc string of generated functions.
+;;     Added renamings of bookmark-name-from(-full)-record, bookmark-get-bookmark-record.
+;; 2011/04/12
+;;     bmkp-define-cycle-command: Use bmkp-sort-omit, not bmkp-sort-and-remove-dups.
+;; 2011/01/03 dadams
+;;     Added autoload cookies: defmacro.
+;; 2010/09/25 dadams
+;;     Added: bmkp-define-next+prev-cycle-commands.
+;; 2010/09/24 dadams
+;;     Added: bmkp-define-cycle-command.
+;; 2010/08/18 dadams
+;;     Removed eval-when-compile for bookmark+-(bmu|1).el.
+;; 2010/08/15 dadams
+;;     Created, from code in other Bookmark+ files.
+ 
+;;;(@* "CHANGE LOG FOR `bookmark+.el'")
+;;
+;; 2021/09/19 dadams
+;;     Version 2021.09.19
+;;     Added option bmkp-bmenu-buffer.
+;;     Autoload bookmark-bmenu-buffer.
+;;     Moved defgroup here, from bookmark+-bmu.el.  Added autoload cookie.
+;; 2021/04/18 dadams
+;;     Version 2021.04.18
+;; 2021/03/04 dadams
+;;     Version 2021.03.04
+;; 2021/02/12 dadams
+;;     Version 2021.02.12
+;; 2020/07/04 dadams
+;;     Version 2020.07.04
+;;     Added defconst for bookmark-bmenu-buffer (Emacs 28).
+;;     Added defvar, make-variable-buffer-local declaration for bookmark-annotation-name (Emacs 28).
+;; 2020/07/03 dadams
+;;     Version 2020.07.03
+;; 2020/01/22 dadams
+;;     Version 2020.01.22
+;; 2020/01/12 dadams
+;;     Version 2020.01.12
+;; 2019/04/22 dadams
+;;     Version 2019.04.22
+;; 2019/04/22 dadams
+;;     Version 2019.02.18
+;; 2018/10/17 dadams
+;;     Version 2018.10.17.
+;; 2018/09/21 dadams
+;;     Version 2017.09.21.
+;; 2017/03/31 dadams
+;;     Version 2017.03.31.  Fixed cycling bookmarks across buffers.  Added other-window cycling cmds.
+;; 2017/02/26 dadams
+;;     Version 2017.02.26.  Added auto-bookmarking for Info.  Better EWW - thx to Charles Roelli.
+;; 2016/11/14 dadams
+;;     Version 2016.11.14.  Added support for EWW bookmarks.  Thx to Charles Roelli.
+;; 2015/02/22 dadams
+;;     Version 2015.02.22.
+;; 2015/02/08 dadams
+;;     Version 2015.02.08
+;; 2015/01/04 dadams
+;;     Version 2015.01.04.
+;; 2013/04/14 dadams
+;;     Added Version entry to header.  Updated bmkp-version-number to the same thing.
+;; 2012/10/09 dadams
+;;     Made all autoload cookies explicitly load bookmark+.el(c).  Should help ELPA (e.g. MELPA).
+;; 2012/06/26 dadams
+;;     Wrapped require of bookmark+-mac.el in eval-when-compile.
+;; 2012/06/21 dadams
+;;     Try to load-library bookmark+-mac.  Require it only if cannot load-library.
+;; 2012/02/26 dadams
+;;     Version 3.4.0.
+;; 2011/12/30 dadams
+;;     Version 3.3.0.
+;; 2011/04/12 dadams
+;;     Version 3.2.2.
+;; 2011/04/01 dadams
+;;     Require bookmark+-key.el (new).  Version 3.2.1.
+;; 2011/01/03 dadams
+;;     Added autoload cookies: defconst, command.
+;; 2010/08/19
+;;     bmkp-version-number: Version 3.2.0.
+;; 2010/08/15 dadams
+;;     Require bookmark+-mac.el.
+;;     Do not ensure loaded before compile (not needed here now).
+;; 2010/07/14 dadams
+;;     Version 3.1.1.
+;;     Moved main content of bookmark+.el to new files bookmark+-1.el and bookmark+-bmu.el.
+;; 2010/07/13 dadams
+;;     Version 3.1.0.
+;;     Added redefinitions: bookmark-bmenu-(1|2)-window, bookmark-bmenu-other-window-with-mouse,
+;;                          bookmark-bmenu-this-window, bookmark-bmenu-switch-other-window.
+;;     Added: bmkp-last-bookmark-file, bmkp-switch-to-last-bookmark-file.
+;;     Removed pre-23 version of bookmark-bmenu-switch-other-window.
+;;     bookmark-load: Use bmkp-last-bookmark-file when read file name.  Added missing prefix arg.
+;;                    Save old current as bmkp-last-bookmark-file.
+;;     bookmark-bmenu-list: If bookmark file has changed do not restore state saved from other file.
+;;                          Save old current as bmkp-last-bookmark-file.
+;;     bmkp-bmenu-list-1: Do not use bmkp-bmenu-title if it is empty ("").
+;;     bookmark-bmenu-mode: Added to doc string: bmkp-switch-bookmark-file.
+;;     bookmark-bmenu-other-window: Do not bind bookmark-automatically-show-annotations (per vanilla).
+;;     bookmark-bmenu-show-annotation: Ensure in bmenu list and on a bookmark line.
+;;     bmkp-switch-bookmark-file: Use bmkp-last-bookmark-file when read file name.
+;;     bmkp-bmenu-define-full-snapshot-command: Set bmkp-last-bookmark-file.
+;;     bmkp-bookmark-description: Fixed typo: bmkp-bookmark-file-bookmark-p (not desktop).
+;;     bmkp-make-bookmark-file-record: Use arg file (not bmkp-non-file-filename) as filename entry.
+;;
+;;     Added more autoload cookies.
+;; 2010/07/09 dadams
+;;     Added: bmkp-bmenu-mark-bookmark-file-bookmarks, bmkp-bmenu-show-only-bookmark-files,
+;;            bmkp-bookmark-file-jump, bmkp-set-bookmark-file-bookmark, bmkp-bookmark-file-history,
+;;            bmkp-use-bookmark-file-create, bmkp-bookmark-file, bmkp-bookmark-file-alist-only,
+;;            bmkp-bookmark-file-bookmark-p, bmkp-jump-bookmark-file, bmkp-make-bookmark-file-record.
+;;     bmkp-types-alist, bmkp-buffer-names, bmkp-bmenu-mode-status-help, bmkp-bmenu-propertize-item,
+;;       bmkp-this-buffer-p, bmkp-last-specific-buffer-p, bmkp-specific-buffers-alist-only,
+;;       bmkp-bookmark-description, bookmark-bmenu-mode:   Updated for bookmark-file bookmarks.
+;;     bookmark--jump-via: Added a catch, so a handler can skip all other processing when it's done.
+;;     bookmark-load: Final msg says whether overwritten.
+;;     Bound and added to menus: bmkp-set-bookmark-file-bookmark,
+;;                               bmkp-bmenu-mark-bookmark-file-bookmarks,
+;;                               bmkp-bmenu-show-only-bookmark-files, bmkp-bookmark-file-jump.
+;; 2010/07/07 dadams
+;;     bookmark-handle-bookmark: Bind use-dialog-box, use-file-dialog to nil.
+;;     bookmark-location: From Emacs 23: Use location property and -- Unknown location --.
+;;     bmkp-switch-bookmark-file: Bind insert-default-directory to nil.
+;;     bmkp-empty-file: Expand FILE.  Return FILE.
+;; 2010/07/03 dadams
+;;     Added: bmkp-bmenu-describe-marked, bmkp-bookmark-description.
+;;     bmkp-describe-bookmark: Rewrote to use bmkp-bookmark-description.
+;;     Bound bmkp-bmenu-describe-marked to C-h >.
+;;     bmkp-bmenu-menubar-menu: Added bmkp-bmenu-describe-(marked|bookmark).
+;;     Updated doc string of bookmark-alist.
+;; 2010/07/01 dadams
+;;     Added: bmkp-bmenu-mark-lighted-bookmarks, bmkp-bmenu-set-tag-value-for-marked,
+;;            bmkp-bmenu-show-only-tagged, bmkp-occur-create-autonamed-bookmarks,
+;;            bmkp-set-autonamed-bookmark, bmkp-set-autonamed-bookmark-at-line,
+;;            bmkp-set-autonamed-regexp-buffer, bmkp-set-autonamed-regexp-region,
+;;            bmkp-set-tag-value-for-navlist, bmkp-prompt-for-tags-flag, bmkp-menu-bar-make-toggle,
+;;            bmkp-same-creation-time-p, bmkp-set-tag-value-for-bookmarks,
+;;            bmkp(-bmenu)-highlight-menu, bmkp-options-menu.
+;;     Renamed: bmkp-use-region-flag to bmkp-use-region,
+;;              bmkp-bmenu-jump-menu to bmkp-jump-menu.
+;;     Removed: bmkp-cycle-this-buffer-buff (unused).
+;;     Soft-require new library bookmark+-lit.el.
+;;     Split off new file bookmark+-chg.el from bookmark+-doc.el.
+;;     Changed default values of faces bmkp->-mark, bmkp-t-mark.
+;;     bmkp-crosshairs-flag: Added :set instead of add-hook at top level.
+;;     bmkp-use-region: Changed from boolean to choice - added cycling-too value.
+;;     bookmark-set: Added INTERACTIVEP arg.  Prompt for tags when bmkp-prompt-for-tags-flag.
+;;                   Auto-highlight when set, per bmkp-auto-light-when-set.
+;;     bookmark--jump-via: Auto-highlight when jump, per bmkp-auto-light-when-jump.
+;;                         Set BOOKMARK to result of bmkp-update-autonamed-bookmark.
+;;                         Bind orig-buff when running hook.
+;;     bookmark-default-handler: Pass the bookmark too as an arg to bmkp-goto-position.
+;;     bookmark-relocate, bookmark-rename, bmkp-bmenu-list-1, bmkp-remove(-all)-tags, bmkp-add-tags:
+;;       Add 0 as FRAME arg to get-buffer-window.
+;;     bookmark-delete: Remove any highlighting on bookmark.
+;;     bmkp-bmenu-list-1: Add highlight-overrides indicator.
+;;     bmkp-completing-read-1: Added (not laxp) guard for first branch of main if.
+;;     bmkp-crosshairs-highlight: Assign a priority.  Make the cmd a no-op for Emacs 20-21.
+;;     bmkp-choose-navlist-*, bmkp-navlist-bmenu-list, bmkp-jump-in-navlist*,
+;;       bmkp-cycle(-this-buffer*):
+;;         Set bmkp-current-nav-bookmark to bookmark, not to its name.
+;;     bmkp-update-autonamed-bookmark: Do not set bmkp-current-nav-bookmark to the name.
+;;                                     Call bmkp-refresh-menu-list even if menu list is not displayed.
+;;                                     Pass the bookmark name to bmkp-refresh-menu-list.
+;;                                     Return the updated BOOKMARK.
+;;     bmkp-refresh-menu-list: Set window point also.
+;;     bmkp-goto-position:
+;;       Added BOOKMARK arg.  When bmkp-save-new-location-flag, update BOOKMARK.  Return indicator.
+;;     bmkp-create-varlist-bookmark: Call bookmark-set with INTERACTIVEP arg.
+;;     bmkp-cycle(-this-buffer*): Added STARTOVERP arg. Pass OTHER-WINDOW, STARTOVERP to bmkp-cycle-1.
+;;     bmkp-cycle-1: Added STARTOVERP arg.  If non-nil pop-up-frames, then inhibit showing annotation.
+;;                   Use region only if bmkp-use-region value is cycling-too.
+;;                   Use eq for *-list-position test.  If *-list-position returns nil, then reset.
+;;                   Use save-selected-window, unlesl OTHER-WINDOW.
+;;     bmkp-(next|previous)-bookmark(-this-buffer|-w32): Added STARTOVERP arg.  C-u: start over at 1.
+;;     Bind highlight cmds: *-map: h,H,u,U,C-u,=,C-up|down.  *-bmenu-*map: H+,H>+,H>H,HH,HS,H>U,HU.
+;;                          *-jump-map: h.  Bind TS in *-bmenu-*map.
+;;     Add bmkp-occur-create-autonamed-bookmarks to occur-mode-map as C-c b.
+;;     Menus: Added Highlight, Toggle Option.  Added light to Jump To, Show, Mark, mouse.  Reorder.
+;; 2010/06/23 dadams
+;;     Split the change log off from file bookmark+-doc.el to new file bookmark+-chg.el.
+;; 2010/06/21 dadams
+;;     Renamed: bmkp-toggle-autoname-bookmark-set/delete to bmkp-toggle-autonamed-bookmark-set/delete,
+;;              bmkp-autonamed-bookmarks-alist-only to bmkp-autonamed-this-buffer-alist-only,
+;;              bmkp-bookmark-autoname-p to bmkp-autonamed-bookmark-for-buffer-p,
+;;     Added: bmkp-autonamed-alist-only, bmkp-non-autonamed-alist-only, bmkp-autonamed-bookmark-p,
+;;     bmkp-completing-read-1: Use DEFAULT as default.  Use just (not lax) - no non-t.
+;;                             Use DEFAULT if empty input only if DEFAULT is non-nil.
+;;     bmkp-choose-navlist-of-type: Added pseudo-type "any".
+;;     bmkp-specific-buffers-alist-only: Exclude desktop etc. bookmarks.
+;;     bmkp-update-autonamed-bookmark: Arg can be a bookmark (not just name).
+;; 2010/06/19 dadams
+;;     RENAMED bookmarkp* TO bmkp*.  ***** THIS IS AN INCOMPATIBLE CHANGE ******
+;;
+;;       If you have existing customizations, or if you have bookmarks that have the (internal) tag
+;;       "bmkp-jump", then YOU MUST REPLACE occurrences of "bookmarkp" by "bmkp" EVERYWHERE.  This
+;;       includes replacing occurrences in (1) your bookmarks file (bookmark-default-file), (2) your
+;;       state file (bmkp-bmenu-state-file), and (3) your command file (bmkp-bmenu-commands-file).
+;;
+;;     Changed *-bmenu-w32-open-select binding to M-o from M-v.
+;; 2010/06/11 dadams
+;;     Wrap all (require '* nil t) in condition-case.
+;; 2010/06/07 dadams
+;;     Fix deskstop bookmarks for Emacs < 22.  Protect:
+;;       *-release-lock with fboundp, *-buffer-args-list with boundp, *-dir with Emacs version #,
+;; 2010/05/30 dadams
+;;     Added: bookmarkp-(next|previous)-bookmark-w32(-repeat).  Bound to C-x p (next|prior).
+;; 2010/05/29 dadams
+;;     *-bmenu-list, *-choose-navlist-from-bookmark-list, *-bmenu-define(-full-snapshot)-command,
+;;       *-save-menu-list-state, -make-bookmark-list-record:
+;;         Add/restore bookmarkp-bmenu-filter-pattern to/from state.
+;;     *-jump-bookmark-list: Set bookmarkp-latest-bookmark-alist to  bookmark-alist.
+;;     Reordered Bookmark menu and added items:
+;;       Set Bookmark, Delete Autonamed Bookmark, Delete All Autonamed Bookmarks Here,
+;;       Delete Bookmarks Here, Delete Bookmark, Rename Bookmark, Bookmark List for This Buffer,
+;;       Bookmark List for Navlist, Set Navlist to Bookmarks of Type,
+;;       Set Navlist from Bookmark-List Bookmark, Insert Bookmark Contents, Insert Bookmark Location.
+;;     Added to Bookmark+ menu: Set Navlist *.
+;;     Added to bookmarkp-bmenu-jump-menu: In Navigation List.
+;;     Added :enable entries for menu items.
+;;     Updated bookmark-bmenu-mode doc string for cycling, navlist, and options.
+;;     Corrected bindings of bookmarkp-jump-in-navlist(-other-window).
+;; 2010/05/26 dadams
+;;     Added:
+;;       bookmarkp-choose-navlist-(from-bookmark-list|of-type), bookmarkp-crosshairs-highlight,
+;;       bookmarkp-cycle(-this-buffer)(-other-window), bookmarkp-delete-bookmarks,
+;;       bookmarkp-jump-in-navlist(-other-window), bookmarkp-navlist-bmenu-list,
+;;       bookmarkp-(next|previous)-bookmark(-this-buffer)(-repeat),
+;;       bookmarkp-toggle-autoname-bookmark-set/delete, bookmarkp-autoname-bookmark(-function),
+;;       bookmarkp-autonamed-bookmarks-alist-only, bookmarkp-autoname-format,
+;;       bookmarkp-bookmark-autoname-p, bookmarkp-crosshairs-flag,
+;;       bookmarkp-this-buffer-cycle-sort-comparer, bookmarkp-current-bookmark-list-state,
+;;       bookmarkp-cycle-1, bookmarkp-list-position, bookmarkp-position-cp,
+;;       bookmarkp-current-nav-bookmark, bookmarkp-cycle-this-buffer-buff, bookmarkp-nav-alist,
+;;       bookmarkp-update-autonamed-bookmark, bookmarkp-delete-all-autonamed-for-this-buffer.
+;;    Bound:
+;;       bookmarkp-choose-navlist-from-bookmark-list, bookmark-insert-location,
+;;       bookmarkp-navlist-bmenu-list, bookmarkp-choose-navlist-of-type, bookmarkp-delete-bookmarks,
+;;       bookmarkp-toggle-autoname-bookmark-set/delete, bookmarkp-jump-in-navlist(-other-window),
+;;       bookmarkp-(next|previous)-bookmark(-this-buffer)-repeat.
+;;    bookmark--jump-via: Update the name and position of an autonamed bookmark.
+;; 2010/05/22 dadams
+;;     *-this-buffer-p: Return nil for bookmarks not really associated with a buffer.
+;;     *-default-handler, *-goto-position: Forgot comma to eval file-name when no-such-file error.
+;;     *-show-annotation: Bind buffer-read-only to nil for updating.
+;; 2010/05/19 dadams
+;;     Added: bookmarkp-this-buffer-bmenu-list.  Bound to `C-x p .'.
+;;     menu-bar-bookmark-map:
+;;       Added bookmarkp-this-buffer-bmenu-list.  Added separators.
+;;       Added vanilla items edit, write, load, to impose order.  Renamed item edit.
+;; 2010/05/16 dadams
+;;     bookmark-set: Quoted history arg.  Thx to S. Nemec.
+;;     bookmarkp-bmenu-define-full-snapshot-command: Use quote comma, not quote, for *-specific-*.
+;; 2010/05/15 dadams
+;;     Replace *same-(buffer|file)-jump* by *specific-(buffers|files)-jump*: read multiple buff/files.
+;;     Renamed: *same-(buffer|file)* to *-last-specific-(buffer|file)* for pred, alist, and var.
+;;     Renamed: *same-(buffer|file)* to *specific-(buffer|file)* for hist, *types*, mark/show cmds.
+;;     Renamed: *-selected-buffers-alist* to *-specific-buffers-alist*.
+;;     Added: *-specific-files-alist*, *-(all|some)-tags(-regexp)-alist-only.
+;;     *-completing-read-(buffer|file)-name: Use (buffer|file)-name-history, not *-same-*-history.
+;;     *-read-tags-completing: Rewrote to correctly handle cons and string tags, error handling, etc.
+;;     *-bmenu-(add|remove)-tags-*-marked: Error handling.
+;;     *(all|some)-tags(-regexp)-jump*: Use *-(all|some)-tags(-regexp)-alist-only.
+;; 2010/05/11 dadams
+;;     Added: bookmarkp-bmenu-mark-same-(buffer|file)-bookmarks, bookmarkp-this-(buffer|file)-p,
+;;            bookmarkp-this-(buffer|file)-alist-only, bookmarkp-bmenu-show-only-same-(buffer|file),
+;;            bookmarkp-completing-read-(buffer|file)-name, bookmarkp-same-(buffer|file)-history,
+;;            bookmarkp-(same|this)-(buffer|file)-alist-only, bookmarkp-last-same-(buffer|file),
+;;            bookmarkp-(same|this)-(buffer|file)-jump(-other-window), bookmarkp-(buffer|file)-names,
+;;            bookmarkp-same-(buffer|file)-as-last-p, bookmarkp-other-window-pop-to-flag,
+;;            bookmarkp-select-buffer-other-window.
+;;     Use bookmarkp-select-buffer-other-window instead of switch-to-buffer-other-window everywhere.
+;;     Bound = (b|f) (M|S), C-x j (=|.) (b|f) to (same|current)-(buffer|file) commands.
+;;     *-types-alist: Handle same-(buffer|file) too.
+;;     *-bmenu-list, *-bmenu-define-full-snapshot-command, *-save-menu-list-state:
+;;       Handle bookmarkp-last-same-(buffer|file) as part of state.
+;; 2010/05/05 dadams
+;;     bookmarkp-create-varlist-bookmark, bookmarkp-make-varlist-record:
+;;       Added optional arg BUFFER-NAME.
+;;     bookmark-alist: Corrected doc string wrt BUFFER-NAME and region context strings.
+;; 2010/05/04 dadams
+;;     Added: bookmarkp-create-varlist-bookmark.
+;;     bookmarkp-jump-varlist: If bookmark's buffer doesn't exist, use current buffer and show msg.
+;; 2010/04/24 adams
+;;     Added: bookmarkp-bmenu-show-only-varlists, bookmarkp-set-restrictions-bookmark,
+;;            bookmarkp-set-varlist-bookmark, bookmarkp-varlist-jump, bookmarkp-varlist,
+;;            bookmarkp-jump-varlist, bookmarkp-make-varlist-record, bookmarkp-printable-p,
+;;            bookmarkp-printable-vars+vals, bookmarkp-read-variables-completing,
+;;            bookmarkp-read-variable, bookmarkp-varlist-alist-only, bookmarkp-varlist-bookmark-p,
+;;            bookmarkp-varlist-history.
+;;     Bound bookmarkp-bmenu-show-only-varlists to V S, bookmarkp-varlist-jump to C-x j v (and menu).
+;;     *-types-alist: Added bookmarkp-varlist-history.
+;;     *-bmenu-mode-status-help, *-bmenu-propertize-item, *-describe-bookmark: Handle varlist bmks.
+;;     *-bmenu-w32-open-select: Changed binding to M-v from V.
+;;     *-bmenu-mode: Updated doc string.
+;; 2010/04/17 dadams
+;;     bookmark-set: Numeric prefix arg means use all bookmarks as completion candidates.
+;;                   Simplified the prompt.
+;;     bookmarkp-completing-read-1:
+;;       Use icicle-transform-multi-completion in icicle-delete-candidate-object
+;;     Ensure loaded before byte-compile (put a require after provide).
+;;     Move bookmarkp-replace-regexp-in-string before macro bookmarkp-define-sort-command (uses it).
+;;     bookmarkp-bmenu-w32-open-with-mouse, bookmarkp-bmenu-mouse-3-menu:
+;;       Use with-current-buffer, not save-excursion of set-buffer.
+;;     bookmarkp-make-dired-record, bookmarkp-jump-dired: Use dolist, not mapcar (just side effect).
+;;     bookmarkp-(some|all)-tags-jump(-other-window): Removed extraneous arg in error call.
+;; 2010/04/16 dadams
+;;     Added: bookmarkp-completing-read-1, bookmarkp-completing-read-lax,
+;;            bookmarkp-selected-buffers-alist-only.
+;;     bookmark-set: Use bookmark-completing-read-lax w/ buffer's bookmarks, not read-from-minibuffer.
+;;     bookmark-completing-read: Define using bookmarkp-completing-read-1.
+;; 2010/04/09 dadams
+;;     bookmarkp-edit-bookmark: Update dired-directory property along with filename property.
+;; 2010/03/28 dadams
+;;     bookmarkp-goto-position: Don't funcall bookmarkp-jump-display-function if it is nil.
+;; 2010/03/28 dadams
+;;     bookmark-default-handler: Don't funcall bookmarkp-jump-display-function if it is nil.
+;; 2010/03/27 dadams
+;;     Changed the customization group from bookmarkp to bookmark-plus.
+;;     Moved doc and change history from bookmark+.el to this new file, bookmark+-doc.el.
+;;     bookmarkp-commentary-button: Use bookmark+-doc.el, not bookmark+.el.
+;; 2010/03/17 dadams
+;;     Added: bookmarkp-toggle-bookmark-set-refreshes, bookmarkp-refresh-latest-bookmark-list,
+;;            bookmarkp-after-set-hook.
+;; 2010/03/16 dadams
+;;     Fixed parens placement (typo) for last change to define *-jump-woman for Emacs 20.
+;; 2010/03/11 dadams
+;;     Define bookmarkp-jump-woman also for Emacs 20 (just raise an error).
+;;     *-show-annotation: Typo: bookmark -> bmk-name.
+;; 2010/03/10 dadams
+;;     Added: bookmarkp-bookmark-creation-cp, bookmarkp-bmenu-sort-by-creation-time (bind: s0, menu).
+;;     *-make-record-default: Add entry: created.
+;;     *-describe-bookmark: Add creation time to description.
+;; 2010/03/03 dadams
+;;     *-sort-and-remove-dups: Do not set bookmarkp-sorted-alist to the result.
+;;     *-bmenu-list-1: Set bookmarkp-sorted-alist to the result of calling *-sort-and-remove-dups.
+;; 2010/03/02 dadams
+;;     Added: bookmarkp-sorted-alist.
+;;     *-bmenu-list-1: Use bookmarkp-sorted-alist.
+;;     *-sort-and-remove-dups: Set bookmarkp-sorted-alist to the result.
+;;     All *-cp (and hence *-define-file-sort-predicate):
+;;       Accept bookmark names as args, in addition to bookmarks.
+;;     bookmark-alpha-p: Don't use bookmarkp-make-plain-predicate, to avoid infinite recursion.
+;; 2010/02/28 dadams
+;;     Added: bookmarkp-send-bug-report.
+;;     bookmarkp-bmenu-mode-status-help: Rewrote to provide only Bookmark+ help.  Added help buttons.
+;;     Fixed Commentary typos.
+;; 2010/02/26 dadams
+;;     Added: bookmarkp-desktop-change-dir, bookmarkp-desktop-kill, bookmarkp-desktop-delete.
+;;     *-jump-desktop: Call *-desktop-change-dir.
+;;     *-read-bookmark-for-type: Added optional arg ACTION.
+;; 2010/02/24 dadams
+;;     *-bmenu-list: Handle case null last-bookmark-file (due to old file format).  Thx to Seb Luque.
+;;     *-make-record-default: protect dired-buffers with boundp.  Thx to Janek Schwarz.
+;; 2010/02/16 dadams
+;;     bookmarkp-define-sort-command: Add msg suffix about repeating.
+;;     bookmarkp-msg-about-sort-order: Added optional arg SUFFIX-MSG.
+;; 2010/02/15 dadams
+;;     Added: bookmark-bmenu-switch-other-window (redefinition for Emacs 20-22).
+;;     *-bmenu-mode: Added redefinition, instead of advising.
+;;     *-send-edited-annotation, *-relocate, *-rename, *-bmenu-refresh-menu-list,
+;;       *-remove(-all)-tags, *-add-tags:
+;;         Refresh the menu list, to pick up changes.
+;;     *-refresh-menu-list: Added optional arg BOOKMARK: go to it.
+;;     Do not bind bookmark-bmenu-relocate unless it's defined.
+;;     *-handler-cp: Respect case-fold-search.
+;; 2010/02/14 dadams
+;;     Renamed bookmark-bmenu-list-1 to bookmarkp-bmenu-list-1.
+;;     Added faces: bookmarkp-(a|t|>|D)-mark, bookmarkp-heading (don't use bookmark-menu-heading).
+;;     Added redefinitions: bookmark-send-edited-annotation, bookmark(-bmenu)-show-annotation,
+;;                          bookmark-show-all-annotations.
+;;     *-bmenu-mark, *-bmenu-delete, *-bmenu-list-1: Add faces to marks.
+;;     *-bmenu-list-1 and everywhere: Get rid of "% " before menu-list title.
+;;     *-bmenu-list-1: Use "a", not "*", as annotation mark.
+;;                     Add "t" mark for tags.  Add an extra space before bookmark name.
+;;     *-bmenu-marks-width: change value from 2 to 4, for the tags column and the extra space.
+;; 2010/02/13 dadams
+;;     Added: bookmarkp-desktop-history,
+;;            bookmarkp-desktop-jump (bound to C-x j K; added to menu),
+;;            bookmarkp-bookmark-list-jump (bound to C-x j B; added to menu),
+;;            bookmarkp-bookmark-list-alist-only, bookmarkp-bookmark-list-history.
+;;     *-types-alist: Added entries for desktops and bookmark-lists.
+;;     *-describe-bookmark: Added optional arg, to show full (internal) info.
+;;                          Bind it to ? in bookmark-map.
+;;     *-jump-bookmark-list: Pop to the bookmark-list (to show it).
+;;     *-bmenu-mark-w3m-bookmarks: Typo: wrong predicate.
+;;     *(-bmenu)-remove-all-tags: Raise error if no tags to remove.
+;;     *-bmenu-remove-all-tags: Require confirmation if interactive.
+;;     *-bmenu-remove-tags: Added optional arg MSGP.
+;;     Menus: Added "..." as needed.
+;;     *-bmenu-mouse-3-menu: Guard bookmark-bmenu-relocate with fboundp.
+;; 2010/02/12 dadams
+;;     Added: bookmarkp-bmenu-define-jump-marked-command.  Bound to M-c and added to menu.
+;;     Changed bookmarkp-toggle-saving-bookmark-file binding to M-~ (M-s conflicts w isearch-multi).
+;;     Updated bookmark-bmenu-mode doc string.
+;; 2010/02/11 dadams
+;;     Added: bookmarkp-types-alist,
+;;            bookmarkp-(dired|gnus|info|man|region|w3m|(non-|local-|remote-)file)-history.
+;;     bookmark-completing-read: Added optional HIST arg.
+;;     *-(relocate|rename|insert(-location)): Added bookmark default for interactive use.
+;;     *-jump-dired: Handle bookmarkp-jump-display-function.
+;;     *-read-bookmark-for-type: Added optional HIST arg.
+;;     *-jump-to-type(-other-window),
+;;       *-(dired|file|gnus|info|man|region|w3m|(local-|non-|remote-)file)-jump*(-other-window):
+;;         Use type-specific history var.
+;; 2010/02/09 dadams
+;;     Added: bookmarkp-get-tag-value.
+;;     bookmark--jump-via: Handle special bookmark tag bookmarkp-jump.
+;; 2010/02/08 dadams
+;;     Renamed: bookmarkp-bmenu-dired-marked-local to bookmarkp-bmenu-dired-marked.
+;;     bookmarkp-bmenu-dired-marked: Handle remote bookmarks if Emacs > 23.1.
+;;     Support tags with values.
+;;       Added: bookmarkp-tag-name, bookmarkp-full-tag, bookmarkp(-bmenu)-set-tag-value.
+;;       Renamed variable (not fn) bookmarkp-tags-list to bookmarkp-tags-alist.
+;;       Use bookmarkp-full-tag everywhere for tag completion.
+;;       *-has-tag-p: Use assoc-default, not member.
+;;       *-read-tag(s)-completing: CANDIDATE-TAGS is now an alist.
+;;       *-list-all-tags: Added optional arg FULLP (prefix arg).
+;;       *-tags-list: Added optional arg NAMES-ONLY-P.
+;;       *-(add|remove|rename)-tags: Use copy-alist, not copy-sequence.  Alist, not list, membership.
+;;       *-rename-tag: Raise error if no tag with old name.
+;;       *-bmenu-mark-bookmarks-tagged-regexp, *-regexp-filtered-tags-alist-only, *-describe-bookmark,
+;;         *-(all|some)-tags-regexp-jump(-other-window):
+;;           Use bookmarkp-tag-name.
+;;       *-bmenu-mark/unmark-bookmarks-tagged-(all|some)/(none|not-all), *-define-tags-sort-command:
+;;         Use assoc-default, not member.
+;;     Added: bookmarkp-bmenu-add-tags, bookmarkp-bmenu-remove(-all)-tags.
+;;     *-bmenu-mouse-3-menu: Use bookmarkp-bmenu-add-tags, bookmarkp-bmenu-remove(-all)-tags.
+;;                           Added bookmarkp-bmenu-set-tag-value.
+;;     *-bmenu-mark-bookmarks-satisfying: Made it a command (interactive).
+;; 2010/02/07 dadams
+;;     *-write-file: Corrected handling of ALT-MSG.
+;;     Cleanup.
+;;       *-remove-tags: Don't call *-get-tags twice.
+;;       *-bmenu-(un)mark-bookmarks-tagged(-not)-(all|none|some):
+;;         Don't duplicate what bookmarkp-read-tags-completing does.
+;;       *-add-tags, *-remove-tags(-from-all): TAGS arg must be a list from the beginning.
+;;       *-remove-tags-from-all, *-rename-tag: Use bookmark-all-names - don't mapcar car over alist.
+;;       *-all-tags-regexp-jump: Corrected to use same pred as *-all-tags-regexp-jump-other-window.
+;;       *-(some|all)-tags-jump(-other-window): Use bookmarkp-has-tag-p - don't repeat the definition.
+;;       *-read-tag(s)-completing: Removed unnecessary or.
+;; 2010/02/06 dadams
+;;     *-write-file, *-empty-file: Corrected handling of ALT-MSG.
+;; 2010/02/05 dadams
+;;     Added: bookmarkp-same-file-p, bookmarkp-empty-file.
+;;     Bound bookmarkp-empty-file to C-x p 0, and added it to menus.
+;;     *-bmenu-list, *-switch-bookmark-file: Use bookmarkp-same-file-p.
+;;     bookmark-write-file: Added optional ALT-MSG arg.
+;; 2010/02/04 dadams
+;;     Added: bookmarkp-bmenu-omit, bookmarkp-list-all-tags.  Added to mouse-3 menu, Tags menus.
+;; 2010/02/01 dadams
+;;     Added: bookmarkp-current-bookmark-file, bookmarkp-switch-bookmark-file,
+;;            (redefinition of) bookmark-load, (redefinition of) bookmark-save,
+;;            bookmarkp-toggle-saving-bookmark-file, bookmarkp-last-save-flag-value.
+;;     *-bmenu-list: Restore bookmarkp-current-bookmark-file if appropriate.
+;;     *-bmenu-mode-status-help: Show bookmarkp-current-bookmark-file.
+;;     *-bmenu-define-full-snapshot-command, *-save-menu-list-state:
+;;       Save bookmarkp-current-bookmark-file.
+;;     Bound bookmarkp-switch-bookmark-file to L and C-x r L.  Added both load commands to both menus.
+;;     *-toggle-saving-menu-list-state: Changed binding to M-l.  Error if init value is nil.
+;;     Bound *-toggle-saving-bookmark-file to M-s and added to menu.
+;;     Added bookmark-write to bookmarkp-bmenu-menubar-menu (Save As).
+;;     bookmarkp-bmenu-menubar-menu: Added :help strings everywhere.
+;;     bookmarkp-bmenu-mode-status-help: Added face legend.
+;; 2010/01/31 dadams
+;;     Added: bookmarkp-tags-list, bookmarkp-read-tag-completing, bookmarkp-use-w32-browser-p,
+;;            bookmarkp-bmenu-w32-open(-select|-with-mouse).  Bind *-w32* to M-RET, V, M-mouse-2.
+;;     *-default-handler: Call w32-browser if bookmarkp-use-w32-browser-p.
+;;     *-bmenu-unomit-marked: Don't try to return to original position (duh).
+;;     *-bmenu-goto-bookmark-named: Use eobp as loop condition.  Call bookmark-bmenu-ensure-position.
+;;     *-read-tags-completing:
+;;       Added arg UPDATE-TAGS-LIST-P.  Call bookmark-maybe-load-default-file.
+;;       Use bookmarkp-tags-list if CANDIDATE-TAGS is nil.  Update that var if UPDATE-TAGS-LIST-P.
+;;     *-(add|remove)-tags: Added arg NO-CACHE-UPDATE-P.  If nil, call bookmarkp-tags-list.
+;;     *-remove-tags-from-all, *-rename-tag, *-bmenu-(add|remove)-tags-(to|from)-marked:
+;;       Call bookmarkp-tags-list.
+;;     *-remove-tags-from-all: Pass nil as tags arg to bookmarkp-read-tags-completing.
+;;     *-rename-tag: Use bookmarkp-read-tag-completing, not read-string.
+;; 2010/01/29 dadams
+;;     bookmarkp-describe-bookmark: Handle desktop bookmarks specifically.
+;;     Added: bookmarkp-menu-popup-max-length.
+;;     bookmark-completing-read: Use bookmarkp-menu-popup-max-length.
+;;     bookmarkp-bmenu-state-file: Added missing default value for const.
+;;     Don't add jump-other entry to menu-bar-bookmark-map (just use Jump To submenu).
+;; 2010/01/28 dadams
+;;     bookmarkp-(all|some)-tags(-regexp)-jump(-other-window): Error if no bookmarks with the tags.
+;;     bookmarkp-(all|some)-tags-jump(-other-window): Handle case where user enters no tags.
+;;     Use :advertised-binding property for bookmark-jump(-other-window).
+;;     Added: bookmarkp-bmenu-jump-menu.
+;;     Added bookmarkp-bmenu-jump-menu to menu-bar-bookmark-map and bookmarkp-bmenu-menubar-menu.
+;; 2010/01/27 dadams
+;;     Added: bookmarkp-every, bookmarkp-(all|some)-tags(-regexp)-jump(-other-window).
+;; 2010/01/26 dadams
+;;     Added: bookmarkp-bmenu-dired-marked-local.  Bound to M-d >.
+;; 2010/01/23 dadams
+;;     Added: bookmarkp-handler-cp, bookmarkp-desktop-no-save-vars, bookmarkp-set-desktop-bookmark,
+;;            bookmarkp-make-desktop-record, bookmarkp-jump-desktop, bookmarkp-desktop-read,
+;;            bookmarkp-desktop-alist-only, bookmarkp-desktop-bookmark-p,
+;;            bookmarkp-bmenu-mark-desktop-bookmarks, bookmarkp-bmenu-show-only-desktops,
+;;            face bookmarkp-desktop.
+;;     bookmarkp-bmenu-sort-by-bookmark-type: Add bookmarkp-handler-cp to the list (last).
+;;     bookmarkp-bmenu-propertize-item: Add face bookmarkp-desktop for desktop bookmarks.
+;;     Bound: bookmarkp-set-desktop-bookmark to C-x p K, C-x r K,
+;;            bookmarkp-bmenu-mark-desktop-bookmarks to K M (and Mark menu),
+;;            bookmarkp-bmenu-show-only-desktops to K S (and Show menu).
+;;     bookmark-bmenu-mode doc string: Updated for new commands.
+;;     Added autoload cookies for all defcustoms.
+;; 2010/01/20 dadams
+;;     Added: bookmarkp-bmenu-mode-status-help.  Bound to C-h m, ?.
+;; 2010/01/19 dadams
+;;     bookmarkp-remote-file-bookmark-p: Include remote Dired bookmarks.  Thx to Simon Harrison.
+;;     Added: bookmarkp-describe-bookmark-internals, bookmarkp-bmenu-describe-this+move-(down|up),
+;;            defalias for list-bookmarks.
+;;     bookmarkp-describe-bookmark: Reformatted help output.  Added more info about Dired bookmarks.
+;;     bookmarkp-bmenu-describe-this-bookmark:
+;;       C-u calls bookmarkp-describe-bookmark-internals.  Bound also to C-h C-RET.
+;; 2010/01/18 dadams
+;;     Added: bookmarkp-dired-subdirs.
+;;     bookmarkp-make-dired-record, bookmarkp-jump-dired: Handle inserted and hidden dirs.
+;;     bookmarkp-jump-dired: Use expand-file-name, not concat.
+;; 2010/01/17 dadams
+;;     Added:
+;;       bookmarkp-jump(-other-window)-map, bookmarkp-jump-1, bookmark-all-names (redefined),
+;;       bookmarkp-read-bookmark-for-type, bookmarkp-dired-jump-current(-other-window),
+;;       bookmarkp-(dired|(local-|remote-|non-)file|gnus|info|man|region|w3m)-jump(-other-window),
+;;       bookmarkp-jump-to-type(-other-window).
+;;     bookmark-jump(-other-window): Use bookmarkp-jump-1.
+;;     bookmark-completing-read: Added optional args ALIST and PRED.
+;;     bookmarkp-default-bookmark-name: Added optional arg ALIST.
+;; 2010/01/14 dadams
+;;     bookmark-bmenu-surreptitiously-rebuild-list: Put back save-excursion & save-window-excursion.
+;; 2010/01/02 dadams
+;;     Renamed *-bmenu-check-position to *-bmenu-ensure-position, per Emacs 23.2.  Added defalias.
+;; 2010/01/01 dadams
+;;     *-bmenu-(un)mark, *-bmenu-other-window, *-bmenu-rename: Call bookmark-bmenu-check-position.
+;;     *-bmenu-delete: Don't call bookmark-bmenu-check-position again at end.
+;;     *-bmenu-edit-bookmark: Call bookmark-bmenu-check-position at beginning, not end.
+;; 2009/12/30 dadams
+;;     Added: bookmarkp-bmenu-header-lines, bookmarkp-bmenu-marks-width.  Use everywhere.
+;; 2009/12/29 dadams
+;;     Added: bookmarkp-make-bookmark-list-record, bookmarkp-jump-bookmark-list, face
+;;            bookmarkp-bookmark-list.
+;;     *-bmenu-propertize-item: Highlight bookmark-list bookmarks.
+;;     *-bmenu-refresh-menu-list: Set bookmarkp-latest-bookmark-alist to refreshed list.
+;;     Face *-local-directory: Made dark background version the inverse of light.
+;;     *-bmenu-list-1: Use eq, not equal, test for bookmarkp-omitted-alist-only as filter fn.
+;;     *-bmenu-define(-full-snapshot)-command: Include bookmarkp-bmenu-omitted-list in saved state.
+;; 2009/12/26 dadams
+;;     Added: bookmarkp-bmenu-omitted-list, bookmarkp-bmenu-show-only-omitted, bookmarkp-unomit-all,
+;;            bookmarkp-bmenu-omit/unomit-marked, bookmarkp-bmenu-(un-)omit-marked,
+;;            bookmarkp-omitted-alist-only.
+;;            Bind *-bmenu-omit/unomit-marked, *-bmenu-show-only-omitted, *-unomit-all to O>,OS,OU.
+;;     Added omit/un-omit stuff to Bookmark+ menu.
+;;     bookmarkp-remove-assoc-dups, bookmarkp-sort-and-remove-dups: Added optional arg OMIT.
+;;     bookmark-delete: Update bookmarkp-bmenu-omitted-list.
+;;     bookmarkp-save-menu-list-state, bookmark-bmenu-list:
+;;       Save/restore bookmarkp-bmenu-omitted-list as part of state.
+;;     bookmark-bmenu-list-1: Treat omitted list when bookmarkp-omitted-alist-only.
+;;     bookmarkp-marked-bookmark-p: Arg can now be a bookmark (or a bookmark name).
+;;     bookmarkp-bmenu-unmark-all: Start by going forward 2 lines, not 1, if user hit RET.
+;;     bookmarkp-bmenu-make-sequence-from-marked:
+;;       Added optional arg DONT-OMIT-P.  If nil, omit marked bookmarks.
+;;       If the seq bookmark already exists, prompt to add to it or replace it.
+;;       Go to the new bookmark in the menu list.
+;; 2009/12/15 dadams
+;;     Added: bookmarkp-sequence-jump-display-function, bookmarkp-sequence, bookmarkp-function,
+;;            bookmarkp-bmenu-make-sequence-from-marked, bookmarkp-jump-sequence,
+;;            bookmarkp-sequence-bookmark-p, bookmarkp-make-function-bookmark,
+;;            bookmarkp-jump-function, bookmarkp-function-bookmark-p.
+;;     bookmarkp-describe-bookmark: Update for sequence and function bookmarks.
+;;     bookmark-bmenu-list: Use condition-case when read from bookmarkp-bmenu-state-file.
+;;                          Bind emacs-lisp-mode-hook to nil.
+;;     bookmark-bmenu-surreptitiously-rebuild-list: Use save-current-buffer.
+;;     bookmarkp-bmenu-propertize-item: Add faces to function and sequence bookmarks.
+;;     bookmarkp-bmenu-menubar-menu: Add *-make-sequence-*-from-marked, *-make-function-bookmark.
+;;     bookmark--jump-via: Call *-record-visit with BATCH arg, to preserver point in menu list.
+;;     bookmark-bmenu-list-1: fit-frame only if buffer is *Bookmark List*.
+;; 2009/12/13 dadams
+;;     *-alist-only: Call bookmark-maybe-load-default-file.
+;; 2009/12/11 dadams
+;;     Added: bookmarkp-list-defuns-in-commands-file, bookmarkp-remove-dups.
+;; 2009/12/06 dadams
+;;     Added: bookmarkp-bmenu-mouse-3-menu (bound to mouse-3),
+;;            bookmarkp-bmenu-(menubar|define-command|sort|show|tags|mark)-menu.
+;;     bookmark-bmenu-delete: Remove newly flagged bookmark from bookmarkp-bookmark-marked-list.
+;;     bookmarkp-define-tags-sort-command: Save macroexpanded definition in
+;;                                         bookmarkp-bmenu-commands-file.
+;; 2009/12/04 dadams
+;;     Added: bookmarkp-bmenu-define-full-snapshot-command (bound to C),
+;;            bookmarkp-define-tags-sort-command.
+;;     bookmarkp-bmenu-mark-bookmarks-tagged-regexp: Removed extra forward-line if we mark line.
+;; 2009/12/03 dadams
+;;     Added: bookmarkp-bmenu-define-command (bound to c), bookmarkp-bmenu-commands-file.
+;;     bookmark-bmenu-list: Read bookmarkp-bmenu-commands-file.
+;;     bookmarkp-sort-and-remove-dups: Bug fix - return the list even when null sort function.
+;; 2009/11/01 dadams
+;;     Added: *-bmenu-check-position (redefinition), bmkext-jump-* defaliases.
+;;     *-(w3m|man|gnus)-bookmark-p: Recognize the aliases.
+;;     *-jump-man: Bind Man-notify-method.
+;;     *-bmenu-goto-bookmark-named: Check the text property, instead of searching.
+;;     *-bmenu-bookmark: Wrap in condition-case.
+;; 2009/10/31 dadams
+;;     Added: bookmark-bmenu-list-1. bookmarkp-toggle-saving-menu-list-state (C-t),
+;;            bookmarkp-bmenu-state-file, bookmarkp-bmenu-first-time-p,
+;;            bookmarkp-last-bmenu-(bookmark|state-file), bookmark-exit-hook-internal
+;;            (redefinition), bookmarkp-save-menu-list-state.
+;;     bookmark-bmenu-list: Restore menu-list state if appropriate.  Call bookmark-bmenu-list-1.
+;;     bookmarkp-bmenu-quit: If *-bmenu-state-file is non-nil, save the state.
+;;     bookmark-write-file: Use case, not cond.
+;;     bookmark-set: Use command name as default for man-page bookmark name.
+;;     bookmark-delete: Update bookmarkp-latest-bookmark-alist.
+;; 2009/10/28 dadams
+;;     Renamed: bookmarkp-bookmark-marked-p to bookmarkp-marked-bookmark-p
+;;              bookmarkp-bmenu-sort-by-gnus-thread to bookmarkp-bmenu-sort-by-Gnus-thread.
+;;     Added: bookmarkp-man, bookmarkp-make-(wo)man-record, bookmarkp-jump-(wo)man,
+;;            bookmarkp-man-bookmark-p, bookmarkp-bmenu-mark-man-bookmarks,
+;;            bookmarkp-bmenu-show-only-man-pages, bookmarkp-man-alist-only.
+;;     *-bmenu-propertize-item: Handle (wo)man bookmarks.  Use bookmarkp-info-bookmark-p.
+;;     *-regexp-filtered-*: Use bookmarkp-remove-if-not.
+;;     *-write-file: Remove text properties from file name also.
+;;     *-regexp-filtered-(tags|(bookmark|file)-name)-alist-only: Use *-remove-if-not.
+;; 2009/10/26 dadams
+;;     Added: bookmarkp-bmenu-mark-*-bookmarks, bmenu-mark-bookmarks-satisfying.
+;;     Bound those and *-show-only-* accordingly.
+;;     bookmarkp-file-alist-only: Redefined to just use *-file-bookmark-p.
+;; 2009/10/25 dadams
+;;     bookmarkp-bmenu-propertize-item: Put bookmark name on line as text property.
+;;     bookmark-bmenu-bookmark: Get bookmark name from text property bookmarkp-bookmark-name.
+;;     Removed: bookmarkp-latest-sorted-alist.
+;;     bookmark-bmenu-list: Use bookmarkp-bmenu-title only if defined.
+;; 2009/10/21 dadams
+;;     Added: bookmarkp-barf-if-not-in-menu-list.  Use in place of its body.
+;;     Added: bookmarkp-bmenu-mark-bookmarks-tagged-regexp.  Bound to T m %.
+;;     Added: bookmarkp-record-visit.  Use in *--jump-via.  Replaces next two removals.
+;;     Removed: bookmarkp-add-or-update-time, bookmarkp-increment-visits.
+;;     Renamed: *-record-(end|front|rear)-context(-region)-string'.
+;;              New names: bookmarkp-(end-)position-(pre|post)-context(-region).
+;;     *-bmenu-describe-this-bookmark: Added *-barf-if-not-in-menu-list.
+;;     *-bmenu-(un)mark-all, *-bmenu-regexp-mark, *-bmenu-toggle-marks:
+;;       Removed with-current-buffer.
+;; 2009/10/20 dadams
+;;     Added: bookmarkp-bmenu-filter-function, bookmarkp-bmenu-title.
+;;     Removed: bookmarkp-bmenu-called-from-inside-p.
+;;     *-bmenu-list:
+;;       Removed TITLE arg.  Get title from bookmarkp-bmenu-title or default.
+;;       Use interactive-p and absence of menu list, not *-bmenu-called-from-inside-p, as the
+;;         criterion for removing marks.  Fixes bugs such as bookmark creation removing marks.
+;;     *-define-sort-command, *-bmenu-execute-deletions, *-increment-visits,
+;;       *-add-or-update-time, *-bmenu-show-only-*, *-bmenu-show-all,
+;;       *-bmenu-refresh-menu-list, *-bmenu-toggle-show-only-(un)marked,
+;;       *-bmenu-filter-alist-by-regexp, *-bmenu-reverse(-multi-sort)-order,
+;;       *-bmenu-change-sort-order:
+;;         Do not bind or set *-called-from-inside-p.
+;;     *-bmenu-show-only-*, *-bmenu-show-all, *-bmenu-filter-alist-by-regexp:
+;;       Set *-bmenu-filter-function, *-bmenu-title.
+;;     *-bmenu-show-all:
+;;       Set *-latest-bookmark-alist to bookmark-alist.
+;;     *-bmenu-refresh-menu-list: Fix so that it in fact refreshes.
+;;       Do not use *-bmenu-surreptitiously-rebuild-list and *-bmenu-check-position.
+;;       Bind bookmark-alist to last alist (filtered or not), and call *-bmenu-list.
+;;     *-bmenu-surreptitiously-rebuild-list:
+;;       Do not use save*-excursion.  Do not get current title and pass it to *-bmenu-list.
+;;     *-file-alist-only:
+;;       Removed optional arg.  We have *-local-file-alist-only for that.
+;;     *-regexp-filtered-alist-only, *-bmenu-filter-alist-by-regexp:
+;;       Remove REGEXP arg - use bookmarkp-bmenu-filter-pattern.
+;;     *-bmenu-filter-incrementally:
+;;       Raise error if not in *Bookmark List*.
+;;       Use just bookmarkp-bmenu-filter-alist-by-regexp in timer - pass no regexp arg.
+;;     Added: bookmarkp-some, *-bmenu-filter-(file-name|tags)-incrementally,
+;;            *-bmenu-filter-alist-by-(file-name|tags)-regexp,
+;;            *-regexp-filtered-(file-name|tags)-alist-only.
+;;     Renamed: *-bmenu-filter-incrementally to *-bmenu-filter-bookmark-name-incrementally,
+;;              *-bmenu-filter-alist-by-regexp to *-bmenu-filter-alist-by-bookmark-name-regexp,
+;;              *-regexp-filtered-alist-only to *-regexp-filtered-bookmark-name-alist-only.
+;;     Bound these commands to P B, P F, and P T.  Updated bookmark-bmenu-mode doc string.
+;; 2009/10/18 dadams
+;;     Added: *-bmenu-filter-(incrementally|delay|prompt|pattern|timer|alist-by-regexp),
+;;            *-bmenu-read-filter-input, *-regexp-filtered-alist-only,
+;;            *-bmenu-cancel-incremental-filtering.
+;;     *-bmenu-execute-deletions: Don't update menu list if this is a no-op.
+;;     Updated Commentary.
+;;     Thx to Thierry Volpiatto.
+;;     Added: *-marked-cp, *-bmenu-sort-marked-before-unmarked.  Bound to s >.
+;;     *-define-sort-command: Use copy-sequence for default value.
+;; 2009/10/17 dadams
+;;     Added: *-read-tags-completing, *-set-union, *-tag-history, *-describe-bookmark,
+;;            *-bmenu-describe-this-bookmark.  Bound *-bmenu-describe-this-bookmark to C-h RET.
+;;     Use *-read-tags-completing instead of *-read-tags.
+;;     *-sort-orders-for-cycling-alist: Use copy-sequence.
+;;     *-bmenu-change-sort-order: Use member, not memq.
+;;     *-get-bookmark: Handle case of non-string, non-cons. Document NOERROR in doc string.
+;;     *-bmenu-execute-deletions: Fix so marks aren't removed if when delete.  Thx to Thierry.
+;;     Convert recorded time to an Emacs time spec:
+;;       *-make-record-default, -add-or-update-time: Use current-time, not bookmark-float-time.
+;;       *-get-visit-time: Convert a deprecated time entry to an Emacs time spec.
+;;       *-bookmark-last-access-cp: Convert recorded time to a number for comparison.
+;;     Added: *-bmenu-show-filenames (redef of vanilla: put props on whole line, fit frame).
+;;     Removed: old-bookmark-insert-location.
+;;     *-insert-location: Do not call original.  Redefined: do not add text properties.
+;;     *-bmenu-list, *-bmenu-hide-filenames: Put properties on line up to max width.
+;;     *-bmenu-goto-bookmark-named: Allow trailing whitespace, since we use the whole line now.
+;;     *-bmenu-list: Use pop-to-buffer, not switch-to-buffer.  Use do-list, not mapcar.
+;;     *-bmenu-hide-filenames: fit-frame-if-one-window.
+;;     *-bmenu-propertize-item: Better help-echo text.
+;;     Updated bookmark-alist doc string to mention visits, time, and tags entries.
+;; 2009/10/16 dadams
+;;     Added tags feature.
+;;       Added: *-(get|read)-tags, *-has-tag-p, *-remove(-all)-tags(-from-all),
+;;              *-bmenu-remove-tags-from-marked, *-add-tags(-to-marked), *-rename-tag,
+;;              *-bmenu-(un)mark-bookmarks-tagged-(all|none|some|not-all),
+;;              *-bmenu-mark/unmark-bookmarks-tagged-(all/none|some/not-all).
+;;       Bound to prefix key T.
+;;       *-bmenu-mode: Updated doc string.
+;;     Added: bookmarkp-default-bookmark-name.  Use as default instead of *-current-bookmark.
+;;     Renamed: *-maybe-save-bookmark to *-maybe-save-bookmarks.
+;;     Menu-list commands: Raise an error if command is used outside the menu list.
+;; 2009/10/15 dadams
+;;     Added: *-bmenu-(search|query-replace)-marked-bookmarks-regexp.  Bound to M-a, M-q.
+;;     Renamed: *-non-marked-bookmarks-only to *-unmarked-bookmarks-only,
+;;              *-bookmark-marked-alist to *-bmenu-marked-bookmarks.
+;;     *-increment-visits, *-add-or-update-time:
+;;       Set *-bmenu-called-from-inside-p to t, so we don't remove marks.
+;;     Redefined *-bmenu-bookmark to get name from *-latest-sorted-alist.  Thx to Thierry V.
+;;       *-bmenu-surreptitiously-rebuild-list, *-bmenu-list:
+;;         Removed optional arg DONT-TOGGLE-FILENAMES-P.
+;;       *-bmenu-execute-deletions, *-bmenu-toggle-show-only-(un)marked, *-bmenu-(un)mark-all,
+;;         *-bmenu-regexp-mark, *-bmenu-toggle-marks:
+;;           Do not bother with *-bmenu-toggle-filenames and rebuilding the menu list.
+;; 2009/10/14 dadams
+;;     Added: *-bmenu-delete (redefinition), *-isearch-bookmarks,
+;;            *-bmenu-isearch(-marked)-bookmarks(-regexp), *-isearch-next-bookmark-buffer.
+;;            Bound multi-isearch commands to M-s a C(-M)-s.
+;; 2009/10/13 dadams
+;;     Added: *-make-dired-record, *-jump-dired, *-dired-bookmark-p, *-dired-alist-only,
+;;            *-bmenu-show-only-dired.  Bound *-bmenu-show-only-dired to M-d.
+;;     bookmarkp-file-bookmark-p: Include bookmarks that have the Dired handler.
+;;     Moved *-sort-orders-for-cycling-alist defcustoms after *-define-sort-command calls.
+;;     Call bookmarkp-msg-about-sort-order only when interactive.
+;;     *-add-or-update-time, *-increment-visits: Do not save each time we access a bookmark.
+;;     Updated doc string of bookmark-alist and Commentary.
+;; 2009/10/09 dadams
+;;     Added: bookmarkp-bmenu-delete-marked.  Bound it to D.
+;;            bookmarkp-sort-orders-for-cycling-alist.
+;;     Renamed: bookmarkp-sort-functions-alist to bookmarkp-sort-orders-alist,
+;;              bookmarkp-sort-function to bookmarkp-sort-comparer.
+;;     bookmark-bmenu-execute-deletions: Added optional arg, for *-bmenu-delete-marked.
+;;     *-sort-function: Changed default value to sorting by bookmark type (`s k').
+;;     *-bmenu-change-sort-order: Use *-sort-orders-for-cycling-alist, not all sort orders.
+;;     Updated Commentary and doc string (bookmark-bmenu-mode).
+;; 2009/10/08 dadams
+;;     Added: *-bmenu-sort-by-(w3m-url|gnus-thread), *-(gnus|w3m)-cp, *-cp-not,
+;;            *-local-file-(accessed|updated)-more-recently-cp, *-bmenu-sort-by-bookmark-type.
+;;     Renamed: *-bmenu-sort-by(-last)-file-(size|type|access|update) to
+;;              *-bmenu-sort-by(-last)-local-file-(size|typeaccess|update),
+;;              *-file-visited-more-recently-cp to *-local-file-accessed-more-recently-cp,
+;;              *-file-(size|type)-cp to *-local-file-(size|type)-cp.
+;;     Removed: *-file-(device|gid(-chg)|inode|last-(access|update|status-change)|links|modes
+;;                            |uid)-cp.
+;;     Bound *-bmenu-sort-by-bookmark-type to `s k'.
+;;     *-define-file-sort-predicate: Use *-file-bookmark-p, not *-local-file-bookmark-p.
+;;     *-msg-about-sort-order: Added optional arg PREFIX-ARG.  Use in: *-show-(all|only-*).
+;; 2009/10/07 dadams
+;;     Renamed: *-bmenu-sort-by-last-visit-time to *-bmenu-sort-by-last-bookmark-access,
+;;              *-bmenu-sort-by-visit-frequency to *-bmenu-sort-by-bookmark-visit-frequency,
+;;              *-visited-more-recently-cp to *-bookmark-last-access-cp.
+;; 2009/10/06 dadams
+;;     Added: bookmarkp-msg-about-sort-order.
+;;     bookmark-completing-read: Simple sort when use menu-bar menu.
+;; 2009/10/05 dadams
+;;     Added: *-make-plain-predicate, *-reverse-multi-sort-order, *-multi-sort,
+;;            *-define-file-sort-predicate, *-bmenu-sort-by-file-*, *-file-attribute-*-cp,
+;;            and aliases *-file-*-cp, *-current-sort-order.
+;;     Redefined sorting to allow multi-predicates:
+;;       Redefined: *-sort-function, *-sort-and-remove-dups, *-define-sort-command,
+;;                  *-sort-functions-alist.
+;;     Bound keys with `s f' prefix to file-sorting commands
+;;     *-current-sort-order: Use rassoc instead of rassq now.
+;;     Swap keys s and S.  S is now bookmark-bmenu-save.  s is not the sorting prefix key.
+;;     bookmark-bmenu-mode: Mention S key explicitly here (even though it is also
+;;                          mentioned in the vanilla part of the doc string).
+;; 2009/10/04 dadams
+;;     *-bmenu-change-sort-order-repeat: Require repeat.el.
+;;     Renamed: bookmarkp-current-sec-time to bookmarkp-float-time.
+;;     *-float-time: Added arg, so it's the same as float-time (for Emacs 20).
+;;     Bind *-reverse-sort-order to `S R'.
+;;     *-remote-file-bookmark-p: Removed extra rem-file in last and.
+;;     *-non-file-bookmark-p: Ensure it's not a remote file, before calling file-exists-p.
+;; 2009/10/03 dadams
+;;     Added: bookmarkp-file-remote-p, bookmarkp-buffer (face).
+;;     bookmarkp-non-file (face): Changed to gray.
+;;     *-default-handler, *-bmenu-propertize-item, *-(info|file)-bookmark-p:
+;;       Support Emacs 20-21 Info-node bookmarks.
+;;     bookmarkp-bmenu-propertize-item: Use different face for existing buffers.
+;;                                      Use bookmarkp-non-file-filename.
+;;     bookmarkp-non-file-bookmark-p: Include buffer bookmarks for nonexistent buffers.
+;;     bookmarkp-remote-file-bookmark-p: Use bookmarkp-file-remote-p.
+;;     bookmark-handle-bookmark:
+;;       Redefine for all Emacs versions.  Handle buffer (non-file) bookmarks.
+;;     Reordered some function definitions.
+;; 2009/10/02 dadams
+;;     Added: bookmarkp-bmenu-goto-bookmark-named, bookmarkp-latest-sorted-alist.
+;;     *-sort-and-remove-dups: Set *-latest-sorted-alist (not used yet).
+;;     *-define-sort-command, *-bmenu-change-sort-order, *-reverse-sort-order:
+;;       Bind *-bmenu-called-from-inside-p to t, to prevent losing marks.
+;;       Restore cursor position to same bookmark after sorting - use *-goto-bookmark-named.
+;;     *-bmenu-surreptitiously-rebuild-list, *-bmenu-list: Added arg DONT-TOGGLE-FILENAMES-P.
+;;     *-bmenu-execute-deletions, *-bmenu-toggle-show-only-(un)marked:
+;;       Call *-surreptitiously-* with arg DONT-TOGGLE-FILENAMES-P.
+;;     *-bmenu-hide-filenames: Simplify - don't get to position by searching backward.
+;;     *-handle-region-default: Use forward-line, not goto-line.
+;;     Thx to Thierry V.
+;; 2009/10/01 dadams
+;;     Added: bookmarkp-some-unmarked-p.
+;;     Renamed: *-bmenu-toggle-show-only-<TYPE> to *-bmenu-show-only-<TYPE>,
+;;              *-bmenu-called-from-inside-flag to *-bmenu-called-from-inside-p.
+;;     bookmarkp-some-marked-p: Do not test bookmarkp-bookmark-marked-alist.
+;;                              Arg must be required (explicit).  Changed calls accordingly.
+;;     bookmark-bmenu-mode: Cleaned up doc string.
+;;     bookmark-bmenu-((un)mark|rename|edit-*|toggle-marks|surreptitiously-rebuild-list),
+;;       bookmarkp-root-or-sudo-logged-p, bookmarkp-jump-w3m-(new-session|only-one-tab),
+;;       bookmarkp-some-marked-p:
+;;         Inline let vars used only once.
+;;     bookmarkp-bmenu-toggle-show-only-marked:
+;;       Test bookmarkp-some-unmarked-p, not bookmarkp-some-marked-p,
+;;            and include *-before-hide-unmarked in the test.
+;;     bookmarkp-bmenu(-toggle)-show-only-*: Display status message.
+;;     bookmarkp-bmenu-toggle-show-only-(un)marked: Fit frame.
+;;     bookmark-prop-set: Fixed, so it handles old bookmark format also.
+;; 2009/10/01 Thierry Volpiatto
+;;     Removed: bookmarkp-bmenu-restore-marks.
+;;     bookmark-bmenu-list:
+;;       Do the mark restoration in line, at the same time as the annotation * restoration.
+;;       Simplify use of START and END.
+;; 2009/09/30 dadams
+;;     bookmarkp-bmenu-regexp-mark: Remove binding of bookmark-alist.
+;;     bookmark-bmenu-(un)mark, bookmarkp-bmenu-edit-bookmark (remove first call only),
+;;       bookmark-bmenu-other-window, bookmark-bmenu-rename, bookmarkp-bmenu-restore-marks:
+;;         Remove bookmark-bmenu-check-position (done by bookmark-bmenu-bookmark anyway).
+;;     bookmark-insert-location: Fix interactive spec for Emacs < 22.
+;;     bookmark-location: Return "" instead of raising error, if no location found.
+;;     bookmarkp-current-sec-time: Move the let: do not call current-time unless we need to.
+;;     bookmarkp-bmenu-unmark-all: forward-line only 1, not 2.  Thx to Thierry.
+;;     bookmark-bmenu-mode: Updated doc string - bindings and mention options.
+;;     bookmarkp-bmenu-propertize-item: For buffer, check also against "   - no file -".
+;; 2009/09/29 dadams
+;;     bookmark-bmenu-unmark: Use delete, not remove.
+;;     Removed: bookmark-bmenu-check-position, bookmarkp-maybe-sort.
+;;     Added: bookmarkp-sort-and-remove-dups, bookmarkp-remove-assoc-dups,
+;;            bookmarkp-face-prop, bookmarkp-bad-bookmark, bookmark-menu-heading (Emacs 20,21),
+;;            bookmark-bmenu-bookmark (redefinition).
+;;     *-bmenu-toggle-show-only-*: Do not call-interactively.
+;;     bookmarkp-bmenu-(un)mark-all:
+;;       Handle bookmark-bmenu-toggle-filenames (wrapper).
+;;       Remove bookmark-bmenu-check-position - just ensure within menu list.
+;;     bookmarkp-bmenu-mark-all: Move save-excursion so it applies to all movements.
+;;                               Message stating number marked.
+;;     bookmarkp-bmenu-unmark-all: Use with-current-buffer ensure in menu list.
+;;                                 Use bookmark-bmenu-unmark.
+;;     Fixed U bindings for bookmarkp-bmenu-unmark-all.
+;;     bookmarkp-bmenu-regexp-mark:
+;;       Remove bookmark-bmenu-check-position - just ensure in menu list.
+;;     bookmarkp-bmenu-toggle-marks: Use forward-line 2, to ensure in menu list.
+;;                                   Message stating number marked.
+;;     bookmark-bmenu-list, bookmarkp-bmenu-propertize-item: Use bookmarkp-face-prop.
+;;     bookmark-bmenu-list: Don't start applying the faces until column 2.
+;;     Removed key bindings in bookmark-map for *-toggle-show-only-*.
+;;     Redefined faces, esp. for a light background.
+;;     Use font-lock-face or face property, depending on Emacs version.
+;;
+;; 2009-06-09 to 2009-09-27 Thierry Volpiatto and dadams
+;;     New features, as follows.
+;;       See also the change log at
+;;         http://mercurial.intuxication.org/hg/bookmark-icicle-region/.
+;;       2090-09-27 Rewrote sorting and unmarking code.  (+ Updates to doc, names.)
+;;                    Unmarking is now like Dired & query-replace.
+;;                    Sorting is via one sort function; sort predicates do all the sorting.
+;;                    Can now cycle sort orders with S S S...
+;;                    Sort cmds now cycle among normal, reverse, off.
+;;                    Add: *-define-sort-command (macro), *-assoc-delete-all, *-upcase,
+;;                         *-get-visits-count, *-get-visit-time, *-sort-functions-alist.
+;;                  Remove docstring from defalias (for Emacs 20).
+;;       2009-09-26 Fix *-bmenu-mode doc (defadvice).
+;;       2009-09-25 *-bmenu-edit, *-bmenu-sort-1: Fix bmk retrieval code.
+;;                  Redefine *-bmenu-unmark.  Add: *-bmenu-toggle-marks.
+;;                  Bind *-bmenu-unmark-all-bookmarks to M-DEL.  Reorder code.
+;;                  Rename: *-bmenu-unmark-all-(bookmarks|(delete|mark)-flag)',
+;;                          *-bmenu-unmark-all-bookmarks-1.
+;;                  Change sort predicates in defalias.  Rename bmk entry visit to visits.
+;;                  Remove: *-bmenu-show-number-of-visit.
+;;       2009-09-22 Rewrote sorting code.  Renamed unmarking fns.
+;;       2009-09-21 Rename mark/unmark cmds to have -bmenu.
+;;                  Add: *-bmenu-called-from-inside-flag - set it in (un)hide marks fns.
+;;       2009-09-20 *-write-file: Remove text properties before saving.
+;;                  Remove all marks only in current display.
+;;       2009-09-19 *-current-sec-time: Protect with fboundp for Emacs 20.
+;;                  *-bmenu-sort-1: Add msg showing sort method.
+;;                  Change key S-A to S-S (A is annotations).
+;;       2009-09-18 Improve sorting by visit frequency.  Always increment when jump.
+;;                  Fix increment visit fn.  Allow sorting by last visited.
+;;                  When visit values are equal, sort with string-lessp.
+;;                  Add TIME bookmark-alist entry.  *-make-record-default: Add time entry.
+;;                  Fix: bad parens, errors in sorting predicate.  Rename fns.  
+;;                  Use single fn to sort using diff methods.
+;;                  Add: *-bmenu-refresh-alist (bind to g).
+;;       2009-09-16 Add: *-toggle-sorting-by-most-visited, *-reset-visit-flag,
+;;                       *-bmenu-show-number-of-visit.
+;;                  Redefine *-prop-set.  Improve *-toggle-sorting-by-most-visited.
+;;                  Add auto-doc to header.  *-bmenu-mode: Add missing key.
+;;                  Update menu-list after jumping.
+;;                  Increment save counter when jump with visit flag.
+;;       2009-09-15 Record number of visits.  Added sorting by most visits.
+;;       2009-09-14 Add doc string.  Update defadvice doc string wrt keys.
+;;       2009-09-12 Add: fns to mark all, unmark D or > or all, *-bmenu-reset-alist.
+;;                  Fix keymap (Emacs 20).  *-unmark-all-bookmarks1: Move the save-excursion.
+;;       2009-09-11 Add: *-bmenu-check-position (redef to improve performance),
+;;                       *-unmark-all-bookmarks, *-current-list-have-marked-p,
+;;                       *-bookmark-marked-p, *-(non-)marked-bookmarks-only.
+;;                  *-bmenu-hide-unmarked: Add toggling.  Restore lost fn.
+;;                  Reorder code.  Bind cmds in *-bmenu-mode-map.
+;;                  *-bmenu-hide-marked: Do not hide if no marked in current filter.
+;;                  Improve: *-bmenu-hide(-not)-marked-bookmark, (un)hide marked fns.
+;;       2009-09-10 Fix *--restore-all-mark, *-bmenu-regexp-mark.
+;;                  *-bmenu-list: Add *-restore-all-mark.
+;;                  *-bmenu-mark: Push marked bmk to marked list.
+;;                  Add: bookmarkp-bookmark-marked-list, *-bmenu-quit.
+;;       2009-09-09 *-maybe-sort-alist: Use copy-sequence.
+;;                  So remove fixes for *-rename, *-edit-bookmark.
+;;                  *-yank, *-rename', *-set: Fix yanking.
+;;                  Remove non-file bmks from file-only list.
+;;                  Add: *-bmenu-list-only-non-file-bookmarks, *-maybe-message (Emacs 20),
+;;                       *-bmenu-mark-bookmark-matching-regexp, *-bmenu-hide-marked-bookmark,
+;;                       *-bmenu-hide-not-marked-bookmark, *-bmenu-mark (redefinition).
+;;                  *-write-file: Improve performance.
+;;                  *-non-file-alist-only: Remove unused def.
+;;                  Fix: hide marked/unmarked with toggle-filenames, keymap for Emacs 20.
+;;                  Improve comments, doc strings.
+;;                  *-bmenu-mark-bookmark-matching-regexp: Fix while loop.
+;;       2009-09-08 bookmark-store: Remove duplicate setq of *-current-bookmark.
+;;       2009-09-07 Reorganize (reorder), add comments, improve doc strings.
+;;                  Change binding of *-bmenu-relocate from R to M-r.
+;;       2009-09-06 bookmark-rename: Redefine with new arg BATCH.
+;;                  *-bmenu-rename: Go to new pos, not old.
+;;                  *-edit-bookmark, bookmark-rename: Fix display update for Emacs 20.
+;;       2009-09-05 Add: *-edit-bookmark, *-bmenu-edit-bookmark, *-maybe-save-bookmark.
+;;       2009-09-04 Require cl.  Allow RET in Emacs 20.  Add doc string.
+;;                  *-fix-bookmark-alist-and-save:
+;;       2009-09-03 Fix *-fix-bookmark-alist-and-save:
+;;                    Use error, not message.  Change value for setcdr.
+;;                    Do not use push with non-var (cl).
+;;                  bookmark-delete:
+;;                    Redefine, to fix vanilla bug: increment count even when BATCHP is non-nil.
+;;                  *-non-file-name: Change to - no file -.  *-bmenu-list: Add arg FILTER-ON.
+;;                  *-bmenu-execute-deletions: Use delete, not remove.
+;;                  Add: *-replace-regexp-in-string.
+;;                  bookmark-set: Fix *-yank-point for region case.  Fix bad parens.
+;;       2009-09-02 Add: *-non-file-filename.  *-fix-bookmark-alist-and-save: Fix msg.
+;;                  Require cl (gensym).  *-at-bol/eol' -> line-*-position (for Emacs 20).
+;;                  Redefine *-bmenu-execute-deletions,
+;;                           *-bmenu-surreptitiously-rebuild-list. 
+;;                  Update current filtered display - do not reload & display all bmks.
+;;                  Add redefinitions of *-bmenu-rename', *-yank-word to fix vanilla bugs:
+;;                    *-bmenu-rename: Do not call *-bmenu-list twice.
+;;                  *-yank-word: Do not insert whitespace.
+;;                  Rename *-last-bookmark-alist-in-use to *-latest-bookmark-alist.
+;;       2009-09-01 Fix: Loading of new doc for bookmark-alist (add vacuous defvar).
+;;                       *-bmenu-(list|hide-filenames): start -> end, end -> start.
+;;                  Removed extraneous quote mark that caused problems.
+;;                  Save only if condition-case exits OK.
+;;       2009-08-31 Fixes: Test for non-file bmk.  Filename for Gnus bmks.
+;;                         Compatibility of bookmark-alist with vanilla Emacs.
+;;                         Require info.el and ffap.el when needed.
+;;                  Add: *-line-number-at-pos (for Emacs 20),
+;;                       *-bmenu-other-window (redefinition).
+;;                  Rename *-propertize-bookmark-list to *-propertize-bmenu-item.
+;;       2009-08-30 Fix: Increment *-alist-modification-count when relocate region,
+;;                       and maybe save.
+;;                  Move code adding properties to bookmarks out of *-bmenu-list.
+;;                  mapc -> mapcar.  *-bmenu-hide-filenames: Redefine.
+;;       2009-08-29 Remove refresh code.
+;;       2009-08-27 Added: *-local-directory-bookmark-p, *-local-file-alist-only,
+;;                         *-non-file-alist-only.
+;;                  *-file-bookmark-p: Redefined to exclude bmks with handlers.
+;;                  Renamed fns and faces.
+;;       2009-08-25 Fit frame after display menu list.
+;;                  Refresh list when toggle filename visibility.
+;;       2009-08-24 Fix: *-bmenu-list for remote files, bookmark-set, *-remote-file-bookmark-p.
+;;                  Ensure arg to file-remote-p is not nil.
+;;                  Recenter region only if it is visible.
+;;       2009-08-23 Remove old *-location.  *-bmenu-list: Add isw3m.
+;;                  bookmark-set:
+;;                    Redefine for older Emacs. Use a default prompt for gnus, w3m.
+;;                    Use *-name-length-max for title when region is active.
+;;                    Ensure bookmark is on one line.
+;;       2009-08-22 Try to handle tramp ftp files.
+;;                  Do not fail if bookmark has empty filename entry.
+;;                  Show region end pos using exchange-point-and-mark.
+;;       2009-08-21 Remove all cl stuff (list*, loop, etc.).  Add *-remove-if(-not).
+;;                  Remove compile-time require of cl.
+;;                  Add predicates *-(region|gnus|w3m|info|(remote-|local-)file)-bookmark-p.
+;;                  Redefine alist-only functions to optimize and use new preds.
+;;       2009-08-20 *--jump-via: Fix to show relocated region before ask whether to save.
+;;                  *-relocate-region: Fix ar-str.  Rename a var.  Add: *-region-activated-p.
+;;                  Revert chgs.
+;;       2009-08-19 Update/fix commentary: bookmark-alist, linkd.
+;;                  *-default-handler, *-handle-region-default:
+;;                    Get bmk record from name only once.
+;;                  *-save-new-region-location: Move t inside progn.
+;;       2009-08-16 Use prefix bookmarkp where appropriate.
+;;       2009-08-15 Improve comments, doc strings.  Rename fns, vars.
+;;                  Add :group with prefix bookmarkp.
+;;       2009-08-09 Fix doc strings.
+;;       2009-08-08 bookmark-set: Update doc string.  Show keys in C-h m.
+;;       2009-08-07 *-jump: Fix to jump in same window (thx to Henry Atting).
+;;                  *-at-bol/eol' -> line-*-position.
+;;       2009-08-01 bookmark-store: Fix for Emacs 20.
+;;       2009-07-27 Ensure we start on an empty w3m buffer.  Add: *-w3m-allow-multi-tabs.
+;;       2009-07-24 *-bmenu-mode-map: Define some new keys.
+;;       2009-07-23 *-bmenu-list: Add path to file in help-echo.
+;;       2009-07-19 Fix title underline.  Highlight bookmark if root logged with tramp.
+;;                  Add face for sudo.
+;;       2009-07-18 Add: filter functions, option for bookmark-bmenu-list.
+;;                  Remove toggle region.
+;;                  *-bmenu-list-only-files-entries: Add prefix arg to show remote.
+;;       2009-07-14 Add a forgotten test.
+;;       2009-07-13 Fix errors.  Give pos in msg even if no search.
+;;                  *-from-bob/eob: Fixed like old strict.
+;;                  Remove *-relocate-region-(method|from-limits).
+;;                  Remove unused code in record fns.  Add: *-relocate-region-function.
+;;       2009-07-12 Do not pass args to relocation routines.  Remove use of flet.
+;;                  Use skip-chars-*ward.  Use forward-line, not beginning-of-line.
+;;                  Remove save-excursion around message.  Correct typo f(ree var BMK).
+;;       2009-07-11 Fix *-relocate-region-strict.  Rename fns, adjust defcustom.
+;;                  Save relocated region after pushing mark.  Add comments.
+;;       2009-07-10 New retrieve fn.  Add looking-* fns.
+;;       2009-07-08 Simplify record fns.  Add doc strings.  Add: *-save-relocated-position.
+;;                  Fix: updating when relocate (wrt new record fns), string closing,
+;;                       free vars, parens, names.
+;;       2009-07-06 Fix: *-bmenu-list wrt windows, Info colors.
+;;       2009-07-04 Rename fns to record, vars, args of retrieve fns.  Big changes, fixes.
+;;       2009-07-01 Fix comments.  *-retrieve-region-strict: improve when out of context.
+;;       2009-06-30 Fix: free vars, *-retrieve-region, provide (name).
+;;       2009-06-29 Fix: w3m handler, file name for non-file, *-simple-retrieve-position.
+;;                  Add: *-retrieve-region-strict.
+;;       2009-06-28 Add: *-retrieve-region-method-is, *-retrieve-region-lax,
+;;                       fns to retrieve regions.
+;;                  Use buffer again, not buffer-name.
+;;       2009-06-27 Fix wrong-type error no such file.  Renamed faces.  Add: *-prop-set.
+;;                  Load gnus at compile time.  Protect tramp-file-name-regexp with boundp.
+;;       2009-06-25 Fixes for older Emacs compatibility.
+;;       2009-06-24 Improve *-default-handler.
+;;                  Add: *-always-save-relocated-position, *-prop-get.
+;;       2009-06-23 Use search-regexp, not re-search-regexp.  Add Gnus bmks.  Add doc.
+;;                  Fix *-bmenu-list.
+;;       2009-06-21 Fix: *-default-handler for Info.  Improve doc strings, commentary.
+;;                  Fixes to be compatible with Emacs 20-22.
+;;                  Use defcustom for *-list-only-regions-flag.
+;;                  *jump: Put prefix arg in interactive spec.  Use buffer-name, not buffer.
+;;                  Remove require of Tramp and inline Tramp fns.
+;;                  Remove tests for display-(color|mouse)-p.
+;;                  w3m-bookmark-(jump|make-record): require w3m.
+;;       2009-06-20 Update context strings when relocate.
+;;                  Fix: bookmark-get-*: search from point-min.
+;;       2009-06-19 Fix: *-make-record-default, *-toggle-use-only-regions, *-default-handler,
+;;                       bookmarking Dired.
+;;                  Handle 4 positions in *-default-handler.
+;;       2009-06-17 Fix: case where some bookmarked text was removed, *-use-region.
+;;       2009-06-15 Fix *-region-alist-only, *-get-buffername, *-location,
+;;                      non-file (buffer) bookmarks.
+;;                  Support w3m similar to Info.
+;;       2009-06-14 Fix bookmark+version, region relocation.  Info support.  Error handling.
+;;       2009-06-13 Fix: *-list-only-regions, *-region-handler, *-make-record, keymap, faces.
+;;                  Put region & info handling in *-default-handler, not separate handlers.
+;;                  Merge *-make-record-region to *-make-record-default.
+;;                  *-jump now negates *-use-region if prefix arg.  Raise error if bad bmk.
+;;       2009-06-12 Add: *-get-endposition, *-region-alist-only-names.
+;;                  Add filter to show only region bookmarks.
+;;                  Faces for menu list.  Change region color.
+;;       2009-06-11 Add: *-region-search-size, *-get-buffername, *-use-region.
+;;                  Redefine *-handle-bookmark, *-jump, to fit bookmark-use-region.
+;;                  Add condtions to bookmark-make-record.  Support w3m.  Support t command.
+;;       2009-06-10 Fix search regexp.  Fix region in Info. Save bookmark if region moves.
+;;       2009-06-09 Added: bookmark-make-record(-region), bookmark-region-handler.
+;;                  Relocation.
+;; 2009/05/25 dadams
+;;     Added redefinition of bookmark-get-bookmark-record.
+;; 2008/10/16 dadams
+;;     bookmark-jump-other-window: Don't define it for Emacs 23+ (not needed).
+;; 2008/04/04 dadams
+;;     bookmark-jump-other-window: Updated wrt Emacs 22.2.
+;; 2007/10/07 dadams
+;;     Added: bookmark-completing-read, bookmark-delete, bookmark-insert(-location),
+;;            bookmark-jump, bookmark-relocate, bookmark-rename.
+;;     bookmark-jump-other-window: Use new bookmark-completing-read.
+;; 2007/07/13 dadams
+;;     Replaced Emacs version tests to reflect Emacs 22 release.
+;; 2006/03/08 dadams
+;;     bookmark-jump-other-window: Handle nil arg.
+;; 2005/05/17 dadams
+;;     Updated to work with Emacs 22.x.
+;; 2004/11/20 dadams
+;;     Refined to deal with Emacs 21 < 21.3.50 (soon to be 22.x)
+;; 2004/10/26 dadams
+;;     Different menu-bar command, depending on Emacs version.
+;; 2004/09/21 dadams
+;;     Only define bookmark-menu-jump-other-window if < Emacs 22.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 3, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+;; You need not load this file.  It contains only documentation.
+
+(provide 'bookmark+-chg)                ; Not used.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; bookmark+-chg.el ends here
diff --git a/lisp/bookmark+-doc.el b/lisp/bookmark+-doc.el
new file mode 100644 (file)
index 0000000..603ed10
--- /dev/null
@@ -0,0 +1,4289 @@
+;;; bookmark+-doc.el - Documentation for package Bookmark+.
+;;
+;; Filename: bookmark+-doc.el
+;; Description: Documentation for package Bookmark+
+;; Author: Drew Adams
+;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com")
+;; Copyright (C) 2000-2022, Drew Adams, all rights reserved.
+;; Created: Fri Sep 15 07:58:41 2000
+;; Last-Updated: Fri Jan 14 12:46:47 2022 (-0800)
+;;           By: dradams
+;;     Update #: 15385
+;; URL: https://www.emacswiki.org/emacs/download/bookmark%2b-doc.el
+;; Doc URL: https://www.emacswiki.org/emacs/BookmarkPlus
+;; Keywords: bookmarks, bookmark+, placeholders, annotations, search,
+;;           info, url, eww, w3m, gnus
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x, 24.x, 25.x, 26.x
+;;
+;; Features that might be required by this library:
+;;
+;;   None
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;    Documentation for the Bookmark+ package, which provides
+;;    extensions to standard library `bookmark.el'.
+;;
+;;    The Bookmark+ libraries are these:
+;;
+;;    `bookmark+.el'     - main (driver) library
+;;    `bookmark+-mac.el' - Lisp macros
+;;    `bookmark+-lit.el' - (optional) code for highlighting bookmarks
+;;    `bookmark+-bmu.el' - code for the `*Bookmark List*' (bmenu)
+;;    `bookmark+-1.el'   - other required code (non-bmenu)
+;;    `bookmark+-key.el' - key and menu bindings
+;;
+;;    `bookmark+-doc.el' - documentation (comment-only - this file)
+;;    `bookmark+-chg.el' - change log (comment-only file)
+;;
+;;    The documentation includes how to byte-compile and install
+;;    Bookmark+.  It is also available in these ways:
+;;
+;;    1. From the bookmark list (`C-x x e' or `C-x r l'):
+;;       Use `?' to show the current bookmark-list status and general
+;;       help, then click link `Doc in Commentary' or link `Doc on the
+;;       Web'.
+;;
+;;    2. From the Emacs-Wiki Web site:
+;;       https://www.emacswiki.org/emacs/BookmarkPlus.
+;;    
+;;    3. From the Bookmark+ group customization buffer:
+;;       `M-x customize-group bookmark-plus', then click link
+;;       `Commentary'.
+;;
+;;    (The commentary links in #1 and #3 work only if put you this
+;;    library, `bookmark+-doc.el', in your `load-path'.)
+;;
+;;    More Bookmark+ description below.
+;;
+;;    To report Bookmark+ bugs: `M-x customize-group bookmark-plus'
+;;    and then follow (e.g. click) the link `Send Bug Report', which
+;;    helps you prepare an email to me.
+;;
+;;
+;;    ****** NOTE ******
+;;
+;;      On 2010-06-18, I changed the prefix used by package Bookmark+
+;;      from `bookmarkp-' to `bmkp-'.  THIS IS AN INCOMPATIBLE CHANGE.
+;;      I apologize for the inconvenience, but the new prefix is
+;;      preferable for a number of reasons, including easier
+;;      distinction from standard `bookmark.el' names.
+;;
+;;      This change means that YOU MUST MANUALLY REPLACE ALL
+;;      OCCURRENCES of `bookmarkp-' by `bmkp-' in the following
+;;      places, if you used Bookmark+ prior to this change:
+;;
+;;      1. In your init file (`~/.emacs') or your `custom-file', if
+;;         you have one.  This is needed if you customized any
+;;         Bookmark+ features.
+;;
+;;      2. In your default bookmark file, `bookmark-default-file'
+;;         (`~/.emacs.bmk'), and in any other bookmark files you might
+;;         have.
+;;
+;;      3. In your `*Bookmark List*' state file,
+;;         `bmkp-bmenu-state-file' (`~/.emacs-bmk-bmenu-state.el').
+;;
+;;      4. In your `*Bookmark List*' commands file,
+;;         `bmkp-bmenu-commands-file' (`~/.emacs-bmk-bmenu-commands.el'),
+;;         if you have one.
+;;
+;;      You can do this editing in a virgin Emacs session (`emacs
+;;      -Q'), that is, without loading Bookmark+.
+;;
+;;      Alternatively, you can do this editing in an Emacs session
+;;      where Bookmark+ has been loaded, but in that case you must
+;;      TURN OFF AUTOMATIC SAVING of both your default bookmark file
+;;      and your `*Bookmark List*' state file.  Otherwise, when you
+;;      quit Emacs your manually edits will be overwritten.
+;;
+;;      To turn off this automatic saving, you can use `M-~' and
+;;      `C-M-~' in buffer `*Bookmark List*' (commands
+;;      `bmkp-toggle-saving-bookmark-file' and
+;;      `bmkp-toggle-saving-menu-list-state' - they are also in the
+;;      `Bookmark+' menu).
+;;
+;;      Again, sorry for this inconvenience.
+ 
+;;(@> "Index")
+;;
+;;  Index
+;;  -----
+;;
+;;  If you have library `linkd.el' and Emacs 22 or later, load
+;;  `linkd.el' and turn on `linkd-mode' now.  It lets you easily
+;;  navigate around the sections of this doc.  Linkd mode will
+;;  highlight this Index, as well as the cross-references and section
+;;  headings throughout this file.  You can get `linkd.el' here:
+;;  https://www.emacswiki.org/emacs/download/linkd.el.
+;;
+;;  (@> "Documentation")
+;;    (@> "Installing Bookmark+")
+;;      (@> "Bookmark+ Load Order and Option `bookmark-default-file'")
+;;    (@> "Bookmark+ Features")
+;;    (@> "Bookmark Basics")
+;;    (@> "Different Types of Jump Commands")
+;;    (@> "Bookmark Annotations")
+;;    (@> "Bookmark Tags")
+;;      (@> "Bookmark Tags Can Have Values")
+;;      (@> "Hierarchical Structures of Bookmarks?")
+;;    (@> "Function, Sequence, Variable-List,... Bookmarks")
+;;      (@> "Little Persistent Named Nothings")
+;;    (@> "Editing Bookmarks")
+;;      (@> "Bookmark Records: What A Bookmark Looks Like")
+;;    (@> "Bookmark-List Views - Saving and Restoring State")
+;;      (@> "Quitting Saves the Bookmark-List State")
+;;      (@> "State-Restoring Commands and Bookmarks")
+;;    (@> "Bookmarking without Visiting the Target")
+;;      (@> "Bookmarking a File or a URL")
+;;      (@> "Bookmarking the Marked Files in Dired")
+;;      (@> "Bookmarking Compilation, Grep, and Occur Hits")
+;;      (@> "Bookmarking Files That You Cannot Visit with Emacs")
+;;      (@> "Opening Bookmarks Using Windows File Associations")
+;;      (@> "Autofile Bookmarks")
+;;      (@> "A Type-Aware `find-file'")
+;;    (@> "Tagging Files")
+;;    (@> "Using Multiple Bookmark Files")
+;;      (@> "Bookmark-File Bookmarks")
+;;    (@> "The Bookmark List Display")
+;;      (@> "Jumping To Bookmarks from the Bookmark List Display")
+;;      (@> "Tag Commands and Keys")
+;;      (@> "Tags: Sets of Bookmarks")
+;;      (@> "Open Dired for the Marked File Bookmarks")
+;;      (@> "Marking and Unmarking Bookmarks")
+;;      (@> "Filtering Bookmarks (Hiding and Showing)")
+;;      (@> "Only Visible Bookmarks Are Affected")
+;;      (@> "Omitting Bookmarks from Display")
+;;      (@> "Sorting Bookmarks")
+;;    (@> "Bookmarks for Specific Files or Buffers")
+;;    (@> "Cycling, Navigation List")
+;;      (@> "The Bookmark Navigation List")
+;;      (@> "Cycling the Navigation List")
+;;      (@> "Cycling Dynamic Sets of Bookmarks")
+;;      (@> "Cycling in the Current File/Buffer")
+;;    (@> "Autonamed Bookmarks - Easy Come Easy Go")
+;;    (@> "Temporary Bookmarks")
+;;      (@> "Temporary Bookmarking Mode")
+;;      (@> "Making Bookmarks Temporary")
+;;    (@> "Automatic Bookmarking")
+;;      (@> "Automatic Bookmarking Using a Hook")
+;;      (@> "Automatic Idle-Period Bookmarking")
+;;      (@> "Automatic Info Bookmarking")
+;;    (@> "Highlighting Bookmark Locations")
+;;      (@> "Defining How to Highlight")
+;;      (@> "Highlighting On Demand")
+;;      (@> "Highlighting Automatically")
+;;    (@> "Using Highlighted Bookmarks")
+;;    (@> "Bookmark Links")
+;;      (@> "Org Mode Links that Jump To Bookmarks")
+;;    (@> "Bookmark Menus")
+;;    (@> "Use Bookmark+ with Icicles")
+;;    (@> "Bookmark Compatibility with Vanilla Emacs (`bookmark.el')")
+;;    (@> "New Bookmark Structure")
+ 
+;;(@* "Documentation")
+;;
+;;  Documentation
+;;  -------------
+;;
+;;(@* "Installing Bookmark+")
+;;  ** Installing Bookmark+ **
+;;
+;;  The main Bookmark+ library is `bookmark+.el'.  The other required
+;;  libraries are `bookmark+-mac.el', `bookmark+-bmu.el',
+;;  `bookmark+-1.el', and `bookmark+-key.el'.  If you want to be able
+;;  to highlight bookmarks then you will also need library
+;;  `bookmark+-lit.el'.  I recommend that you byte-compile all of the
+;;  libraries, after loading the source files (in particular, load
+;;  `bookmark+-mac.el').
+;;
+;;  Put the directory of these libraries in your `load-path' and add
+;;  this to your init file (~/.emacs):
+;;
+;;  (require 'bookmark+)
+;;
+;;  That will load all of the Bookmark+ libraries.  If you do not care
+;;  about bookmark highlighting then simply do not put
+;;  `bookmark+-lit.el' in your `load-path'.
+;;
+;;  By default (see option `bmkp-crosshairs-flag'), when you visit a
+;;  bookmark that has no region it is highlighted temporarily using
+;;  crosshairs, for easy recognition.  (This temporary highlighting is
+;;  independent of the highlighting provided by `bookmark+-lit.el'.)
+;;
+;;  For this optional crosshairs feature you also need library
+;;  `crosshairs.el', which in turn requires libraries `col-highlight',
+;;  `hl-line', `hl-line+', and `vline'.  Library `hl-line' comes with
+;;  vanilla Emacs.  The others are available from the Emacs Wiki web
+;;  site: https://www.emacswiki.org/.  You also need Emacs 22 or later
+;;  for this feature.
+;;
+;;
+;;(@* "Bookmark+ Load Order and Option `bookmark-default-file'")
+;;  *** Bookmark+ Load Order and Option `bookmark-default-file' ***
+;;
+;;  Standard option `bookmark-default-file' defines the default
+;;  location of your bookmark file.  Bookmark+ does not change the
+;;  value.  You can change the value, of course, either by customizing
+;;  it (recommended) or using Lisp code (including in your init file).
+;;
+;;  However, the value of `bookmark-default-file' is used when you
+;;  load Bookmark+ to initialize some other variables, in particular
+;;  option `bmkp-last-as-first-bookmark-file' and internal variable
+;;  `bmkp-current-bookmark-file'.
+;;
+;;  This means that if you modify `bookmark-default-file' in your init
+;;  file, and you want your new value to be take into account by
+;;  Bookmark+, then modify it before you load Bookmark+.
+;;
+;;  Be aware also that another library that you load might, itself,
+;;  load Bookmark+, in which case you will for the same reason want to
+;;  load that library after you have modified `bookmark-default-file'.
+;;  An example of this is Icicles, which loads Bookmark+ if Bookmark+
+;;  is in your `load-path'.
+;;
+;;  In general, with Bookmark+ I recommend that you simply set option
+;;  `bookmark-default-file' once and for all at the outset, preferably
+;;  by customizing it.  You can use `bmkp-switch-bookmark-file-create'
+;;  at any time to switch to a different bookmark file - it is bound
+;;  to `C-x x L'.  You can also invoke it in your init file, provided
+;;  Bookmark+ has already been loaded.
+;;
+;;  See Also: (@> "Using Multiple Bookmark Files")
+ 
+;;(@* "Bookmark+ Features")
+;;  ** Bookmark+ Features **
+;;
+;;  Here is an overview of some of the features that Bookmark+
+;;  provides.  Some of these are detailed in other sections, below.
+;;
+;;  * Richer bookmarks.  They record more.  They are more accurate.
+;;
+;;     - An optional bookmark annotation is user-supplied text that is
+;;       saved as part of the bookmark.  You can use any text you
+;;       like, and you can use it for any purpose you like.  In
+;;       Bookmark+, the mode for viewing and editing a bookmark
+;;       annotation is Org mode, by default.
+;;
+;;     - In addition, Bookmark+ lets you optionally use a separate
+;;       file, URL, or bookmark to annotate any bookmark.  Accessing
+;;       ("showing") such an external annotation visits its
+;;       destination.  So for example, you can use bookmarks to one or
+;;       more Org files to annotate one or more bookmarks.  The
+;;       annotation saved with the bookmark itself just specifies the
+;;       destination.  See (@> "Bookmark Annotations").
+;;
+;;     - You can tag bookmarks, a la del.icio.us.  In effect, tags
+;;       define bookmark sets.  A bookmark can have any number of
+;;       tags, and multiple bookmarks can have the same tag.  You can
+;;       sort, show/hide, or mark bookmarks based on their tags.
+;;
+;;     - Bookmark+ tags can be more than just names.  They can be
+;;       full-fledged user-defined attributes, with Emacs-Lisp objects
+;;       as their values.
+;;
+;;     - You can have multiple bookmarks with the same name.  This is
+;;       particularly useful for autofile bookmarks, which are
+;;       bookmarks that have the same name as their target files or
+;;       directories.  They give you the effect of using files or
+;;       directories themselves as bookmarks.  In particular, they let
+;;       you, in effect, tag files and directories.
+;;       See (@> "Autofile Bookmarks") and (@> "Tagging Files").
+;;
+;;       (In vanilla Emacs you can also, in theory, have multiple
+;;       bookmarks with the same name.  But you cannot really use them
+;;       in any practical way.  Vanilla Emacs cannot distinguish among
+;;       them: the most recent one shadows all others with the same
+;;       name.)
+;;
+;;     - Bookmarks record the number of times you have visited them
+;;       and the time of the last visit.  You can sort, show/hide, or
+;;       mark bookmarks based on this info.
+;;
+;;     - You can combine bookmarks, to make composite, or sequence,
+;;       bookmarks.  Invoking a sequence bookmark invokes each of its
+;;       component bookmarks in turn.  A component bookmark can itself
+;;       be a sequence bookmark.
+;;
+;;     - You can bookmark a region of text, not just a position.  When
+;;       you jump to a bookmark that records a region, the region is
+;;       activated (see option `bmkp-use-region').  (Region activation
+;;       is not supported for Gnus bookmarks.)
+;;
+;;       You can define your own region handler for bookmarks that
+;;       record regions.  (This is in addition to being able to define
+;;       bookmark handlers.)  Use option `bmkp-handle-region-function'
+;;       for this.  As one example, command
+;;       `bmkp-region-jump-narrow-indirect-other-window' binds the
+;;       option to a function that narrows the targeted region in a
+;;       cloned indirect buffer.  (You need library
+;;       `narrow-indirect.el' for this command.)
+;;
+;;     - Bookmarks are relocated better than for vanilla Emacs when
+;;       the contextual text changes.
+;;
+;;  * Additional ways to bookmark.
+;;
+;;     - You can bookmark the file or URL named at point (or any other
+;;       file or URL), without first visiting it.
+;;
+;;     - You can bookmark the targets of the hits in a compilation
+;;       buffer or an `occur' buffer, without first visiting them.
+;;
+;;     - You can bookmark all of the marked files in Dired at once.
+;;
+;;  * Additional types of bookmarks.
+;;
+;;    Bookmark+ adds over 70 types of bookmark. (You can see what they
+;;    all are by invoking function `bmkp-types-alist'.) Here are the
+;;    main ones:
+;;
+;;     - Autofile bookmarks.  You can bookmark a file without visiting
+;;       it or naming the bookmark.  The bookmark name is the same as
+;;       the file name (nondirectory part).  You can have multiple
+;;       such bookmarks with the same name, to bookmark files with the
+;;       same name but in different directories.
+;;
+;;     - Dired bookmarks.  You can bookmark a Dired buffer, recording
+;;       and restoring its `ls' switches, which files are marked,
+;;       which subdirectories are inserted, and which (sub)directories
+;;       are hidden.
+;;
+;;     - Dired-tree bookmarks.  A set of Dired bookmarks that
+;;       represent a directory hierarchy and are opened together.
+;;
+;;     - Bookmark-list bookmarks.  You can bookmark the current state
+;;       of buffer `*Bookmark List*' - a list of bookmarks.  Jumping
+;;       to such a bookmark restores the recorded sort order,
+;;       markings, filter, title, and omit list.
+;;       See (@> "Omitting Bookmarks from Display").
+;;
+;;     - Bookmark-file bookmarks.  You can bookmark a bookmark file.
+;;       Jumping to such a bookmark loads the bookmarks in the file.
+;;       See (@> "Bookmark-File Bookmarks").
+;;
+;;     - Desktop bookmarks.  You can bookmark the current Emacs
+;;       desktop, as defined by library `desktop.el' - use command
+;;       `bmkp-set-desktop-bookmark' (`C-x x K').  You can "jump" to a
+;;       desktop bookmark (that is, restore its saved desktop).  A
+;;       desktop includes:
+;;
+;;         - Some global variables.  To exclude variables normally
+;;           saved, see option `bmkp-desktop-no-save-vars'.
+;;        - The current set of buffers and their associated files.
+;;           For each: its mode, point, mark, & some local variables.
+;;
+;;       If option `bmkp-desktop-jump-save-before-flag' is non-`nil',
+;;       and if the current desktop was made current by jumping to a
+;;       bookmark, then it is saved before jumping to the next
+;;       desktop.  If you want to save the last desktop jumped to when
+;;       you quit Emacs, then add `bmkp-desktop-save-as-last' to
+;;       `kill-emacs-hook'.
+;;
+;;     - Gnus bookmarks.  You can bookmark a Gnus article, a URL, a
+;;       PDF file (DocView), a UNIX manual page (from the output of
+;;       Emacs command `man' or `woman'), an image, or a piece of
+;;       music.
+;;
+;;     - Non-file (buffer) bookmarks.  You can bookmark a buffer that
+;;       is not associated with a file.
+;;
+;;     - Function bookmarks.  A bookmark can represent a Lisp
+;;       function, which is invoked when you "jump" to the bookmark.
+;;
+;;     - Sequence (composite) bookmarks.  A bookmark can represent a
+;;       sequence of other bookmarks.
+;;
+;;     - Keyboard-macro bookmarks, bookmarks for sets of keyboard
+;;       macros, and sequence bookmarks that combine another bookmark
+;;       with a keyboard macro.
+;;
+;;     - Lisp variable bookmarks.  A bookmark can represent a set of
+;;       variables and their values.
+;;
+;;     - Snippet bookmarks.  Select some some text and give it a
+;;       (bookmark) name.  Then copy it to the `kill-ring' anytime, in
+;;       any Emacs session.
+;;
+;;     - Icicles search-hits bookmarks.  (You need library Icicles to
+;;       use this feature.)  During Icicles search you can use `C-x
+;;       C-M->' to save the current set of completion candidates
+;;       (search hits matching your current input) as an Icicles
+;;       search-hits bookmark.  During a later Icicles search you can
+;;       retrieve those search hits saved in the bookmark, by using
+;;       `C-x C-M-<`.  You can add to (instead of replacing) the
+;;       current set of hits with hits retrieved from a bookmark using
+;;       `C-x C-<'.  This is the only way you can "jump" to such a
+;;       bookmark.
+;;
+;;     In particular, note that you can use the following kinds of
+;;     bookmarks to quickly switch among different projects (sets of
+;;     bookmarks): Dired, Dired tree, bookmark-list, bookmark-file,
+;;     and desktop bookmarks.
+;;
+;;  * Type-specific jump commands.
+;;
+;;     - When you want to jump to a bookmark of a specific type
+;;       (e.g. Dired), you can use a command that offers only such
+;;       bookmarks as completion candidates.
+;;
+;;     - You can also use generic command `bmkp-jump-to-type', bound
+;;       to `C-x j :'.  It prompts you for the bookmark type, then
+;;       offers only bookmarks of that type as completion candidates.
+;;
+;;  * Define your own new bookmark types.
+;;
+;;    Just as for vanilla Emacs, you can easily define your own
+;;    bookmark types, by defining a function to create its record,
+;;    using function `bookmark-make-record', or by binding variable
+;;    `bookmark-make-record-function' for a given context.
+;;
+;;    But you can also make jumping to a new type of bookmarks
+;;    type-specific, usable with `bmkp-jump-to-type' (`C-x j :') or
+;;    with your own type-specific jump command.
+;;
+;;    For that, just:
+;;
+;;    1. Define a function `bmkp-TYPE-alist-only', which returns an
+;;       alist of bookmarks that are only of your new TYPE, for use
+;;       with `bookmark-completing-read'.  The alist should have the
+;;       same form as `bookmark-alist'.  (And you can use your alist
+;;       for more than just completion.)
+;;
+;;    2. Evaluate `(bmkp-define-history-variables)', to add a history
+;;       variable for your type, again, for use with
+;;       `bookmark-completing-read'.
+;;
+;;  * Extensive menus.
+;;
+;;     - In the `*Bookmark List*' display, a `mouse-3' popup menu has
+;;       actions for the individual bookmark that you point to when
+;;       you click the mouse.
+;;
+;;     - In the `*Bookmark List*' display, a complete menu-bar menu,
+;;       `Bookmark+', is available.  The same menu is available on
+;;       `C-mouse-3'.  It has submenus `Jump To', `Mark', `Omit',
+;;       `Show', `Sort', `Tags', `Highlight' (needs library
+;;       `bookmark+-lit.el), and `Define Command'.
+;;
+;;     - The vanilla `Bookmarks' menu, which is typically a submenu of
+;;       the menu-bar `Edit' menu, is modified by adding several items
+;;       from the `Bookmark+' menu, including submenus `Jump To',
+;;       `Tags', and `Highlight'.
+;;
+;;     - Bookmark+ adds two items to the menu bar `Edit' menu:
+;;
+;;       . Save the active region text as a bookmark.
+;;       . Jump to the bookmark to copy the text to the kill ring, so
+;;         you can then yank it anywhere.
+;;
+;;     - Some modes provide a `Bookmarks Here' menu-bar submenu with
+;;       items to access bookmarks for the current file/buffer.
+;;       Display of this menu is controlled by option
+;;       `bmkp-add-bookmarks-here-menu-flag' (`nil' by default
+;;       because computing the menu can take a little time).
+;;
+;;  * Improvements for the bookmark-list display.
+;;
+;;    This is buffer `*Bookmark List*', aka the bookmark "menu list"
+;;    (a misnomer), which you display using `C-x x e' (or `C-x r l').
+;;    See (@> "The Bookmark List Display").
+;;
+;;     - The last display state is saved (by default), and is restored
+;;       the next time you show the list.  (Tip: Use the bookmark list
+;;       as your "Home" page at Emacs startup.)
+;;
+;;     - You can save the current bookmark-list state at any time and
+;;       return to it later.  There are a few ways to do this,
+;;       including bookmarking the list itself.
+;;       See (@> "Bookmark-List Views - Saving and Restoring State").
+;;
+;;     - Marking/unmarking is enhanced.  It is similar to Dired's.
+;;
+;;     - You can easily mark or show different classes of bookmarks.
+;;
+;;     - Faces distinguish bookmarks by type.
+;;
+;;     - You can sort bookmarks in many ways.  You can easily define
+;;       your own sort orders, even complex ones.
+;;
+;;     - You can regexp-search (`M-a') or query-replace (`M-q') the
+;;       targets (destination file or buffers) of the marked
+;;       bookmarks, in the current bookmark-list sort order.  For
+;;       Emacs 23 and later, you can even search incrementally (`M-s a
+;;       C-s', or `M-s a C-M-s' for regexp).
+;;
+;;     - You can use `M-d >' to open Dired for just the local file
+;;       bookmarks that are marked (`>').
+;;
+;;     - If you use Emacs on Microsoft Windows, you can open bookmarks
+;;       according to Windows file associations.  (You will also need
+;;       library `w32-browser.el'.)
+;;
+;;     - You can use (lax) completion when you set a bookmark using
+;;       `C-x r m' (`bmkp-bookmark-set-confirm-overwrite'), choosing
+;;       from existing bookmarks for the same buffer.  This makes it
+;;       easy to update a nearby bookmark (e.g. relocate it).  With a
+;;       numeric prefix argument (or if there are no bookmarks for the
+;;       buffer), you can choose from all bookmarks.
+;;
+;;     - You can edit a bookmark: its name and file name/location, its
+;;       tags, or its complete defining internal Lisp record.
+;;
+;;     - The mode line shows the number of bookmarks that are marked
+;;       (`>'), flagged for deletion (`D'), tagged (`t'), temporary
+;;       (`X'), annotated (`a'), and modified (unsaved) (`*').  It
+;;       also shows the current sort order.
+;;
+;;       For each of the number indicators (e.g., the number marked):
+;;
+;;       If the current line has the indicator (e.g. `>') and there
+;;       are other lines with the same indicator that are listed after
+;;       the current line, then the indicator shows `N/M', where N is
+;;       the number indicated through the current line and M is the
+;;       total number indicated.  Otherwise, it shows just `N'.
+;;
+;;       This feature is available starting with Emacs 24.3.  (For
+;;       prior versions I removed it because Emacs bug #12867 can
+;;       cause Emacs to crash.)
+;;
+;;  * Multiple bookmark files.
+;;
+;;     - Although vanilla Emacs lets you load different bookmark
+;;       files, it does not support this feature well, and the
+;;       behavior can even be contradictory.  With Bookmark+ you can
+;;       easily (a) switch among alternative bookmark files or (b)
+;;       load multiple files into the same session, accumulating their
+;;       bookmark definitions.  The last file you used is the default
+;;       when you choose a file to switch to, so it is easy to go back
+;;       and forth between two bookmark files.
+;;       See (@> "Using Multiple Bookmark Files").
+;;
+;;  * Dedicated keymaps as prefix keys.
+;;
+;;     - Prefix `C-x x' is used for bookmark keys, in general.  The
+;;       vanilla keys on prefix `C-x r' are still available also, but
+;;       that prefix is shared with register commands, making it less
+;;       convenient for bookmarks.  Using `C-x x' lets you focus on
+;;       bookmarks.
+;;
+;;     - Prefix `C-x x c' is for setting various kinds of bookmarks.
+;;
+;;     - Prefixes `C-x j' and `C-x 4 j' (for other-window) are used
+;;       for bookmark jump commands.  Again, a dedicated prefix key
+;;       helps you focus on one kind of action (jumping).
+;;
+;;     All of these prefix keys correspond to prefix-map variables, so
+;;     you need not use these particular prefixes.  You can bind these
+;;     maps to any prefix keys you want.  These are the maps, together
+;;     with their predefined bindings.
+;;
+;;       `bookmark-map'               - `C-x x'
+;;       `bmkp-set-map'               - `C-x x c'
+;;       `bmkp-tags-map'              - `C-x x t'
+;;       `bmkp-jump-map'              - `C-x j'
+;;       `bmkp-jump-other-window-map' - `C-x 4 j'
+;;
+;;     Those are the prefix keys that are available by default.  To
+;;     change them, just customize these user options, each of which
+;;     is a list of the key sequences to use as prefix key.
+;;
+;;     - `bmkp-bookmark-map-prefix-keys'          - default: ("^Xp")
+;;     - `bmkp-jump-map-prefix-keys'              - default: ("^Xj")
+;;     - `bmkp-jump-other-window-map-prefix-keys' - default: ("^X4j")
+;;
+;;     (`^X' here is actually the Control-X character.)
+;;
+;;     Keymaps `bmkp-set-map' and `bmkp-tags-map' are always on
+;;     `bookmark-map', whatever prefix keys it is on.  So if, for
+;;     example, you customize `bmkp-bookmark-map-prefix-keys' to be
+;;     ("^Xp" [f9]) then the keys in `bmkp-set-map' have both prefix
+;;     `C-x x c' and prefix `<f9> c'.
+;;
+;;     In addition to keys on Bookmark+ keymaps, Bookmark+ binds some
+;;     mode-specific bookmarking commands in some other modes: Occur,
+;;     Compilation (including Grep), Buffer-menu, EWW, Gnus, Info,
+;;     Man, Woman, W3M, and Dired (if you use library `Dired+').
+;;     These keys let you set or jump to bookmarks specific to the
+;;     modes.
+;;
+;;  * Helpful help.
+;;
+;;     - Information about individual bookmarks.
+;;
+;;       . Anywhere in Emacs, `C-x h M'  (command
+;;         `bmkp-describe-bookmark') describes any bookmark.  With a
+;;         prefix argument, it shows you the full information that
+;;         defines it (internal form).
+;;
+;;       . With the cursor on a highlighted bookmark, `C-x x ?' shows
+;;         the same description, and a prefix argment has the same
+;;         effect (show internal form).
+;;
+;;       . Hovering your mouse over a highlighted bookmark shows the
+;;         same description, in a tooltip.  Actually, you can
+;;         customize the description using option
+;;         `bmkp-tooltip-content-function'.  The default value is
+;;         `bmkp-bookmark-description', which describes the bookmark.
+;;         A value of `bmkp-annotation-or-bookmark-description', for
+;;         example, shows the bookmark annotation if there is one, or
+;;         the full description if not.
+;;
+;;       . In the bookmark list, `C-h RET' (or `C-h C-RET') describes
+;;         the bookmark under the cursor.  The description is as
+;;         complete as possible - for example, for an image-file
+;;         bookmark the complete EXIF image metadata is shown.  (This
+;;         is only for Emacs 22 and later, and only if you have
+;;         command-line tool `exiftool' installed.  See standard Emacs
+;;         library `image-dired.el' for more information about
+;;         `exiftool'.)
+;;
+;;         And again, a prefix arg (`C-u C-h RET') means show the full
+;;         (internal) bookmark information.
+;;
+;;         `C-h >' shows the same information that `C-h RET' shows,
+;;         but for all of the marked bookmarks, in the current sort
+;;         order.  That is, it describes each of the marked bookmarks.
+;;
+;;         `C-down' and `C-up' move the cursor down and up a line,
+;;         respectively, but they also show the description of the
+;;         bookmark corresponding to the new cursor location.  This is
+;;         a quick way to cycle among bookmark descriptions, in the
+;;         current sort order.
+;;
+;;     - General Bookmark+ documentation.
+;;
+;;       . Anywhere in Emacs, `M-x bmkp-bmenu-mode-status-help' shows
+;;         detailed information about the current state of the
+;;         bookmark list.  Click button `Doc in Commentary' or button
+;;         `Doc on the Web' to access the complete documentation.
+;;
+;;         (Use button `Customize' to customize all Bookmark+
+;;         faces and options.)
+;;
+;;       . In the bookmark list, `?' and `C-h m' are the same as `M-x
+;;         bmkp-bmenu-mode-status-help'.  (`C-h m' in the bookmark
+;;         list does not show you info about minor modes.  If you want
+;;         that, use `M-x describe-mode'.)
+;;
+;;       . In the `bookmark-plus' group customization buffer (`M-x
+;;         customize-group bookmark-plus'), click button `Commentary'.
+;;
+;;       . From the Emacs-Wiki Web site,
+;;         https://www.emacswiki.org/emacs/BookmarkPlus.
+;;
+;;     - It is easy to recognize orphaned and invalid bookmarks.
+;;
+;;       . Invalid bookmarks are shown in a special face in the
+;;         bookmark-list display.
+;;
+;;       . You can easily mark all of the orphaned bookmarks, that is,
+;;         those whose recorded files have been renamed or deleted.
+;;         You can then relocate or delete those bookmarks.
+;;
+;;     - It is easy to recognize modified (i.e., unsaved) bookmarks.
+;;       They are marked with `*'.  Likewise, bookmarks that have tags
+;;       (marked with `t'); bookmarks that have annotations (`a'); and
+;;       bookmarks that are temporary (`X'), meaning that they will
+;;       not be saved.
+;;
+;;  * Jump-destination highlighting.
+;;
+;;     - When you jump to a bookmark, the destination (position) is
+;;       highlighted temporarily using crosshairs, to make it stand
+;;       out.  Option `bmkp-crosshairs-flag' controls this, and this
+;;       feature is available only if you also use library
+;;       `crosshairs.el'.
+;;
+;;  * Visual bookmarks (highlighting).
+;;
+;;     - You can highlight the locations of bookmarks, either
+;;       automatically or on demand.  You control what kind of
+;;       highlighting, if any, is used for which bookmarks.  This
+;;       feature requires that you have library `bookmark+-lit.el' in
+;;       your `load-path' (it will then be loaded by `bookmark+.el).
+;;
+;;  * Better, user-configurable bookmark-name defaults.
+;;
+;;     See the doc strings of command `bookmark-set' (Bookmark+
+;;     version) and options `bmkp-new-bookmark-default-names' and
+;;     `bmkp-default-bookmark-name'.
+;;
+;;  * Synergy with `Icicles'.
+;;
+;;     - `Icicles' works with Bookmark+ to provide enhanced bookmark
+;;       jumping (visiting), setting, and help.  It gives you a
+;;       bookmark browser, and lets you bookmark and tag files on the
+;;       fly.  See (@> "Use Bookmark+ with Icicles") and
+;;       https://www.emacswiki.org/emacs/Icicles.
+ 
+;;(@* "Bookmark Basics")
+;;  ** Bookmark Basics **
+;;
+;;  Bookmark+ builds on vanilla Emacs bookmarks.  If you are familiar
+;;  with the latter, then you can skip this section, which mostly
+;;  reviews the former.  However, this section also introduces some
+;;  Bookmark+ concepts and features that are detailed in other
+;;  sections.
+;;
+;;  In Emacs bookmarking these three things are different but related:
+;;
+;;  1. the bookmark list
+;;  2. the bookmark file
+;;  3. the bookmark-list display (buffer `*Bookmark List*', aka the
+;;     bookmark "menu list", a misnomer)
+;;
+;;  It is important to keep these three straight and understand their
+;;  differences in practice, in particular, when they do and do not
+;;  represent the same set of bookmarks.
+;;
+;;  #1 is in memory.  It is the current set of bookmarks.  When you
+;;  add, rename, delete, etc. a bookmark, this list is updated.
+;;
+;;  #2 is on disk.  It is a persistent record of a set of bookmarks.
+;;
+;;  The bookmark list (#1) is the current value of internal variable
+;;  `bookmark-alist'.  The bookmark file (#2) can be anywhere.  Its
+;;  default filename is the value of user option
+;;  `bookmark-default-file'.
+;;
+;;  The bookmark list is typically initialized from the bookmark file
+;;  - referred to as loading your bookmarks, but you can also create
+;;  bookmarks (adding them to the list) without ever saving them to
+;;  disk.
+;;
+;;  The bookmark list can be saved to the bookmark file - referred to
+;;  as saving your bookmarks - either automatically or on demand.  But
+;;  it is not necessarily saved.  Even if it has been saved in the
+;;  past, that does not mean that at any given time the bookmark list
+;;  corresponds exactly to the bookmark file.
+;;
+;;  The list and the file can often become out of sync.  In an Emacs
+;;  session, the bookmark list rules.  After an Emacs session, the
+;;  bookmark file rules (it is all there is).  You can use `C-x x L'
+;;  (`bmkp-switch-bookmark-file-create') to sync (revert) the list to
+;;  reflect the file - just accept the default value, "switching" to
+;;  the same file.
+;;
+;;  The bookmark-list display (#3) is a snapshot view of the bookmarks
+;;  in the bookmark list.  As such, what you see there reflects the
+;;  state of the bookmark list at some point in time.  So here again,
+;;  the two, list and display, can be out of sync.  Hitting `g' in the
+;;  bookmark-list display refreshes it to accurately reflect the
+;;  current bookmark list (#1).  Some other operations in the display
+;;  also keep it synced with the list.
+;;
+;;  Using a prefix argument (`C-u g') syncs the display (#3) and the
+;;  list (#1) to the file (#2).  This can be useful when some other
+;;  process (e.g., another Emacs session) updates the bookmark file or
+;;  when you want to abandon changes to the current bookmark list and
+;;  any of the current bookmarks.  Outside the bookmark-list display,
+;;  you can use command `bmkp-revert-bookmark-file' to do this.
+;;
+;;  You can load different bookmark files, either adding their
+;;  bookmarks to those already in the current bookmark list or
+;;  replacing them.
+;;
+;;  The most important takeaway from this section is that #1 (list),
+;;  #2 (file), and #3 (display) can be out of sync, and they often
+;;  are.  And that can be useful.
+;;
+;;  Until now, everything said in this section is true of vanilla
+;;  Emacs as well as Bookmark+.  Bookmark+ adds some flexibility
+;;  regarding the use of multiple bookmark files, and it can save the
+;;  last state of the bookmark-list display for later reuse.
+;;
+;;  The saved state of the display is restored when you show the
+;;  display after quitting it (`q') in the same session or quitting
+;;  Emacs, but only if the bookmark file whose location it recorded is
+;;  the same as the current bookmark file.
+;;
+;;  It would not make sense to display a completely different set of
+;;  bookmarks from those that are currently loaded.  The display must
+;;  always reflect the current bookmark list (even if it sometimes
+;;  reflects it imperfectly, because it is a snapshot).  So if the
+;;  bookmark file that is loaded is different from the one that was
+;;  recorded for the display state, the recorded state is ignored.
+;;
+;;
+;;(@* "Automatic Saving")
+;;  *** Automatic Saving ***
+;;
+;;  Before getting into the topic of automatic saving, let me say this
+;;  clearly once: BACK UP YOUR BOOKMARK FILE(S)!
+;;
+;;  (Bookmark+ creates backups when your bookmark file is saved.
+;;  Until bug #12507 is fixed, vanilla Emacs does not.)
+;;
+;;  I recommend that you set option `bookmark-version-control' to `t',
+;;  so that you get numbered backups.
+;;
+;;  If you do use numbered backups then you might also want to
+;;  customize option `delete-old-versions', setting the value to `t',
+;;  so that you are not bothered by this prompt each time bookmarks
+;;  are saved:
+;;
+;;    Delete excess backup versions of <YOUR-INIT-FILE>? (y or n)
+;;
+;;  See also nodes `Backup Names' and `Backup Deletion' in the Emacs
+;;  manual.
+;;
+;;  User option `bookmark-save-flag' controls whether and how often to
+;;  automatically save the bookmark list to the bookmark file, thus
+;;  syncing the two.  You can toggle this option using `M-~' in the
+;;  bookmark-list display.
+;;
+;;  In the bookmark-list display, you can tell whether individual
+;;  bookmarks have been modified since the last save: they are marked
+;;  with `*'.  I believe that this indication is robust and accurate
+;;  (if not, please report a bug), but a word of caution: do not
+;;  depend on it.  The only way to be sure that your bookmarks have
+;;  been saved is to save them. ;-)
+;;
+;;  Is there a way to unmodify a single bookmark that you have
+;;  changed?  No, not unless it is the only one you modified.  If you
+;;  revert to the bookmarks as last saved, then all changes to all
+;;  bookmarks (including addition and removal of bookmarks) are lost.
+;;  If you want to work carefully when making multiple changes, then
+;;  save any modifications you are sure of before you move on to
+;;  others.  If only one bookmark is modified then reverting to the
+;;  bookmark file effectively unmodifies that bookmark.
+;;
+;;  When you consult the doc for option `bookmark-save-flag' you see
+;;  that besides values of `nil' and `t', meaning off and on, it can
+;;  have a value that is the number of bookmark modifications to allow
+;;  before automatically saving.  If the value is 10, for instance,
+;;  then the 11th modification triggers automatic saving.
+;;
+;;  But a modification means any change to any bookmark.  Typically,
+;;  you are more interested in considering all of the changes caused
+;;  by a given command as one modification.  Why?  Suppose you use a
+;;  command such as `T > +' (`bmkp-bmenu-add-tags-to-marked'), which
+;;  adds a set of tags to each of the marked bookmarks.  Even if there
+;;  have been no other modifications since you last saved bookmarks,
+;;  if there are more marked bookmarks than your setting of
+;;  `bookmark-save-flag' then automatic saving will kick in in the
+;;  middle of the command.  Some of the bookmarks with the added tags
+;;  will be automatically saved.  And that does not give you an
+;;  opportunity to cancel the changes (e.g., by quitting without
+;;  saving).
+;;
+;;  This is the reason for option `bmkp-count-multi-mods-as-one-flag',
+;;  whose default value is `t', which means count all of a sequence of
+;;  modifications together as one modification, as far as
+;;  `bookmark-save-flag' is concerned.
+ 
+;;(@* "Different Types of Jump Commands")
+;;  ** Different Types of Jump Commands **
+;;
+;;  When you jump to a bookmark, you can use completion to specify the
+;;  bookmark name.  `bookmark-jump' and `bookmark-jump-other-window',
+;;  bound to `C-x j j' and `C-x 4 j j', are general commands.  Their
+;;  completion candidates include all of your bookmarks.  With
+;;  Bookmark+ you can easily have a large number of bookmarks.
+;;
+;;  To provide more specificity, Bookmark+ provides many different
+;;  bookmark jump commands.  If you want to jump to a bookmark of a
+;;  specific type, such as Info, you can use a Bookmark+ command that
+;;  is specific to bookmarks of that type: only those bookmarks are
+;;  completion candidates.
+;;
+;;  There are thus type-specific commands: `bmkp-dired-jump',
+;;  `bmkp-info-jump', and so on, bound to `C-x j d', `C-x j i', and so
+;;  on.  There are also commands to jump to bookmarks for the current
+;;  buffer or for particular buffers or files
+;;  (see (@> "Bookmarks for Specific Files or Buffers")).
+;;
+;;  All bookmark jump commands are bound to keys that have the prefix
+;;  `C-x j'.  There is an other-window version of most jump commands,
+;;  and it is bound to the same key as the same-window command, except
+;;  the prefix is `C-x 4 j', not `C-x j'.  For instance,
+;;  `bmkp-dired-jump-other-window' is bound to `C-x 4 j d'.
+;;
+;;  (In the bookmark-list display, you can use just `j' instead of
+;;  `C-x 4 j', and just `J' (uppercase) instead of `C-x j'.)
+;;
+;;  More precisely, the bookmark jump commands are on the prefix maps
+;;  `bmkp-jump-map' and `bmkp-jump-other-window-map', which have the
+;;  default bindings `C-x j' and `C-x 4 j'.  You can bind these maps
+;;  to any keys you like, by customizing options
+;;  `bmkp-jump-map-prefix-keys' and
+;;  `bmkp-jump-other-window-map-prefix-keys'.
+;;
+;;  If you do not remember the different type-specfic bindings, you
+;;  can use commands `bmkp-jump-to-type' and
+;;  `bmkp-jump-to-type-other-window' (`C-x j :' and `C-x 4 j :').
+;;  They work for any type, prompting you first for the type, then for
+;;  a bookmark of that type (only).
+;;
+;;  There are several commands for jumping to a bookmark with tags.
+;;  The completion candidates can be those bookmarks that have all
+;;  tags in a given set, some tags in a given set, all tags matching a
+;;  regexp, or some tags matching a regexp.  You are prompted for the
+;;  set of tags or the regexp to match.
+;;
+;;  These commands all have the prefix key `C-x j t'.  The suffix key
+;;  is `*' for "all" and `+' for "some".  The regexp-matching commands
+;;  precede the suffix key with `%'.  For example, `C-x j t % +' jumps
+;;  to a bookmark you choose that has one or more tags that match the
+;;  regexp you input.
+;;
+;;  There are some type-specific jump commands for bookmarks with
+;;  tags.  The key sequences for these include a key that indicates
+;;  the bookmark type, after the `t' indicating tags.  For example,
+;;  commands for jumping to a file or directory bookmark having
+;;  certain tags use the prefix `C-x j t f' (`f' for file).  Similar
+;;  commands for autofile bookmarks have prefix `C-x j t a' (`a' for
+;;  autofile).
+;;
+;;  For example, `C-x j t f % *' jumps to a file or directory bookmark
+;;  you choose, where all of its tags match a regexp, and `C-x j t a
+;;  +' finds a file tagged with at least one of the tags you input.
+;;
+;;  In addition to the ordinary autofile "jump" commands, there are
+;;  `find-file' versions: they read a file name using
+;;  `read-file-name', instead of completing a bookmark name.  - see
+;;  (@> "Autofile Bookmarks").  These commands are available starting
+;;  with Emacs 22.
+;;
+;;  Bookmark names are global.  File names are not; that is, the
+;;  nondirectory portion is not.  Suppose you have two similar
+;;  directories with some like-named files, perhaps tagged in similar
+;;  ways.  Imagine image files of your vacations organized in
+;;  different directories by year.  It is sometimes useful to narrow
+;;  your focus to the file bookmarks in one directory.
+;;
+;;  Commands such as `bmkp-file-this-dir-jump' (`C-x j . f') offer as
+;;  completion candidates only bookmarks for files and subdirs in the
+;;  current directory (`default-directory').  For tags, there are
+;;  equivalent commands.  For example, `C-x j t . % *' is the same as
+;;  `C-x j t f % *', but the destinations are limited to files in the
+;;  current directory.  All of the "this-dir" file jump commands are
+;;  bound to the same keys as the general file jump commands, but with
+;;  `.' instead of `f'.
+;;
+;;  Remember that Bookmark+ collects lots of commands on only a few
+;;  predefined prefix keys, primarily as a mnemonic device.  Nothing
+;;  requires you to use the long key sequence `C-x j t f % *' to visit
+;;  a file that has a given set of tags.  It is expected that you will
+;;  bind short key sequences to commands that you use often.
+;;
+;;  The `C-x j' and `C-x 4 j' bindings are global.  In addition, in
+;;  some modes `j' is bound to the corresponding type-specific jump
+;;  command.  For example, in Info mode, `j' is bound to
+;;  `bmkp-info-jump'.  (Dired is an exception here: `J' is used
+;;  instead of `j', since `j' is already taken for `dired-goto-file'.)
+;;  These commands are also added to the mode's menu-bar menu.
+;;
+;;  In Dired mode, `C-j' is bound to a special Dired-specific jump
+;;  command, `bmkp-dired-this-dir-jump', whose destinations all use
+;;  the current directory (`default-directory').  The aim of `C-j' is
+;;  not to change directories but to change to a different set of
+;;  Dired markings, switches, inserted subdirectories, or hidden
+;;  subdirectories for the same Dired directory.
+;;
+;;  In addition to the predefined bookmark types, which you can use as
+;;  described above, you can define a "type"-specific jump command for
+;;  any set of bookmarks.  That is, you can use any specific set of
+;;  bookmarks as the completion candidates for a new jump command.
+;;  Such a set is really only a pseudo-type: the actual bookmarks can
+;;  each be of any type.
+;;
+;;  You could use this feature, for example, to define a jump command
+;;  for the bookmarks that belong to a given project.
+;;
+;;  One way to define such a command is to first mark the bookmarks
+;;  that you want to be the completion candidates, then use `C-c C-j'
+;;  (command `bmkp-bmenu-define-jump-marked-command') in the bookmark
+;;  list.
+;;
+;;  The `*Bookmark List*' display defines a set of bookmarks, even
+;;  without markings.  So does each bookmark of type bookmark list,
+;;  that is, a bookmark corresponding to a particular `*Bookmark
+;;  List*' display state - see
+;;  (@> "State-Restoring Commands and Bookmarks").
+;;
+;;  You can capture the set of bookmarks corresponding to a `*Bookmark
+;;  List*' display for use in navigation, that is, as the current
+;;  "navigation list".  Navigation here includes jumping and cycling
+;;  - see (@> "Cycling, Navigation List").
+;;
+;;  To capture in the navigation list the bookmarks corresponding to
+;;  either the current `*Bookmark List*' display or a bookmark-list
+;;  bookmark, use `C-x x B', which is bound to command
+;;  `bmkp-choose-navlist-from-bookmark-list'.  To then jump to a
+;;  bookmark from such a navigation list, use `C-x j N' or `C-x 4 j N'
+;;  (`bmkp-jump-in-navlist' or `bmkp-jump-in-navlist-other-window').
+ 
+;;(@* "Bookmark Annotations")
+;;  ** Bookmark Annotations **
+;;
+;;  With Bookmark+ you can bookmark many kinds of Emacs object.
+;;  Bookmarks record locations - that is their primary purpose.  They
+;;  can also record annotations: general free-text descriptions of
+;;  your choosing.  An annotation is thus metadata that is associated
+;;  with a bookmark.  You can use it for any purpose you like.
+;;
+;;  Command `bookmark-show-annotation' shows an annotation in
+;;  read-only mode.  You can use `C-x C-q' in the annotation buffer to
+;;  switch to edit mode (and back again).
+;;
+;;  You can use command `bookmark-edit-annotation' or `bmkp-annotate'
+;;  anywhere to edit the annotation for a bookmark.  For
+;;  `bookmark-edit-annotation', you can choose among the bookmarks
+;;  that already have annotations.  With a prefix arg, you can choose
+;;  any bookmark (and so create an annotation).  Using `bmkp-annotate'
+;;  is the same as using `bookmark-edit-annotation' with a prefix arg.
+;;
+;;  In the annotation edit buffer, make your changes and then use `C-c
+;;  C-c' to save the result.  Use `C-x C-k' if you do not want to save
+;;  the changes.  You can also use `C-x C-q' and then `y' to confirm
+;;  reverting the changes.
+;;
+;;  Non-`nil' user option `bookmark-automatically-show-annotations'
+;;  means that a bookmark's annotation is popped up whenever you jump
+;;  to the bookmark.  If the non-`nil' value is `edit' then the
+;;  annotation buffer is in edit mode; if it is any other non-`nil'
+;;  value then the buffer is in show (read-only) mode.
+;;
+;;  In the `*Bookmark List*' display, bookmarks with annotations are
+;;  marked by an `a' to the left of the bookmark name.  You can use `a
+;;  a' to show the annotation for the bookmark on the current line.
+;;  You can use `a e' to create an annotation or edit an existing
+;;  annotation for it.  You can use `a >' to edit annotations for all
+;;  of the marked bookmarks.  You can use `a A' to show a list of the
+;;  names and annotations of all annotated bookmarks.
+;;
+;;  A bookmark annotation is stored as part of the bookmark itself.
+;;  For this reason, you typically want to keep the text fairly short.
+;;  In Bookmark+, the mode for viewing and editing a bookmark
+;;  annotation is Org mode, by default.  (To change the mode used,
+;;  customize option `bmkp-annotation-modes-inherit-from'.)
+;;
+;;  You can obtain the effect of using longer annotations, and some
+;;  other advantages as well, by using "external annotations".  These
+;;  are annotations that are short and serve only as pointers to
+;;  external files, URLs, or other bookmarks.
+;;
+;;  Whenever you show the annotation of a bookmark (via `a' in the
+;;  `*Bookmark List*' display, `bookmark-show-annotation', or
+;;  `bookmark-automatically-show-annotations') and the annotation is
+;;  such a pointer, the effect is to visit the destination.
+;;
+;;  So for example, you can use bookmarks to one or more Org files to
+;;  annotate (provide metadata for) one or more other bookmarks.
+;;
+;;  You create an external annotation for a bookmark by using one of
+;;  these forms as the annotation text.
+;;
+;;     bmkp-annot-url: "FILE"
+;;     bmkp-annot-url: "URL"
+;;     bmkp-annot-url: "BOOKMARK"
+;;
+;;  * FILE is an absolute file name.  It is handled by
+;;    `find-file-other-window'.
+;;  * URL is a URL.  It is handled by `browse-url'.
+;;  * BOOKMARK is the name of a bookmark in the current bookmark
+;;    alist.
+;;
+;;  The double-quote characters are necessary here, so that you can
+;;  include characters such as `SPC' in the name.  The text must be on
+;;  the first line of the annotation (not counting the commented
+;;  instruction lines).  It can be preceded only by whitespace.
+;;
+;;  You can include other text in the annotation, after the
+;;  destination specification, and you can see or edit it when you
+;;  edit the annotation (e.g., using `C-u a' in buffer `*Bookmark
+;;  List*'), but it is ignored when the annotation is "shown" (e.g.,
+;;  using `a').
+;;
+;;  In the `*Bookmark List*' display, `M-down' and `M-up' move the
+;;  cursor down and up a line, respectively, but they also show the
+;;  annotation, if any, of the bookmark at the new cursor location.
+ 
+;;(@* "Bookmark Tags")
+;;  ** Bookmark Tags **
+;;
+;;  In addition to annotating bookmarks with arbitrary metadata,
+;;  Bookmark+ bookmarks can also be tagged, as a way to organize them,
+;;  which also means as a way to organize the objects that are
+;;  bookmarked.
+;;
+;;  By "tagging" and "tag" in this context is meant associating
+;;  keywords or other text with an object, typically in order to
+;;  classify or characterize it.  Tags are metadata about an object.
+;;  This notion of tagging is sometimes called "delicious" tagging
+;;  after the Web site www.delicious.com that popularized it
+;;  (`https://en.wikipedia.org/wiki/Delicious_(website)').
+;;
+;;  Be aware that there is another notion of "tag" associated with
+;;  Emacs: that involving Emacs tags files, which record the locations
+;;  of function, variable, etc. definitions in source files.  There is
+;;  no relation between the two notions of "tag".
+;;
+;;  A bookmark tag is a string (or a cons whose car is a string - see
+;;  (@> "Bookmark Tags Can Have Values")).  You can add as many tags
+;;  as you like to any bookmark, and multiple bookmarks can have the
+;;  same tag(s).  In fact, that's the whole idea behind using them for
+;;  organizing.
+;;
+;;  This feature is unrelated to the fact that bookmarks record
+;;  locations and are useful for navigating.  You can, if you want,
+;;  use bookmarks to tag files in various ways purely for purposes of
+;;  organizing them (e.g. into projects), whether or not you ever use
+;;  the bookmarks as a way to visit them.
+;;
+;;  For example, if you use `Dired+' (library `dired+.el'), then you
+;;  can use `M-b' (`diredp-do-bookmark') in Dired to create an
+;;  autofile bookmark for each of the marked files and subdirectories
+;;  in the Dired buffer.  Even if you never use those bookmarks for
+;;  navigating to their targets, you can use them with tags to
+;;  organize the targets, and thus operate on subsets of the marked
+;;  files and subdirectories.
+;;
+;;  And if you use libraries `Dired+' and `highlight.el' then
+;;  autofiles are highlighted specially in Dired, and the highlighting
+;;  indicates whether the file is tagged.
+;;
+;;  By default, you create bookmarks without tags and add tags to them
+;;  later.  If you prefer, you can customize option
+;;  `bmkp-prompt-for-tags-flag' to non-`nil' so that you are prompted
+;;  to add tags immediately whenever you set (create or update) a
+;;  bookmark.  
+;;
+;;  There are also some commands, such as `bmkp-tag-a-file' (`C-x x t
+;;  + a') and `bmkp-untag-a-file' (`C-x x t - a'), that always prompt
+;;  for tags to add or remove.  (In general, the key `a' is used in
+;;  key sequences for autofile bookmarks.)
+;;
+;;  When you are prompted to enter a tag, you type some text then hit
+;;  `RET'.  If you want to include a newline character in the tag
+;;  itself, use `C-q C-j' (`C-j' is the newline character).  You can
+;;  use `C-q' this way to enter any character.  If you do use complex
+;;  strings as tags then you might prefer to simply edit a bookmark's
+;;  tags in a separate buffer.  You can do that using `C-x x t e' (or
+;;  `T e' in the bookmark-list display).
+;;
+;;  Whenever you are prompted for a tag you can use completion.  The
+;;  completion candidates available are the tag names defined by
+;;  option `bmkp-tags-for-completion'.  The default value of this
+;;  option is `current', meaning use only the tags from the bookmarks
+;;  in the current bookmark list as candidates.  You can customize the
+;;  option to include specific tags or the tags from bookmarks in
+;;  specific bookmark files.
+;;
+;;  You can use command `bmkp-list-all-tags' to list all of the tags
+;;  defined by option `bmkp-tags-for-completion' or, with a numeric
+;;  prefix argument, only the tags corresponding to the current
+;;  bookmark file.  You can list the tag names only or (using a
+;;  non-negative prefix arg) show the full tag definitions, which
+;;  include any associated tag values (see (@> "Bookmark Tags Can Have Values")
+;;  for information about tag values).
+;;
+;;  To make tags more useful, Bookmark+ provides *lots* of commands:
+;;  commands for adding, removing, copying, pasting, and renaming
+;;  tags; commands for jumping to bookmarks with particular sets of
+;;  tags; and commands for marking or unmarking (in buffer `*Bookmark
+;;  List*') bookmarks that are tagged in various ways.
+;;
+;;  Most commands pertaining to tags are by default on prefix key `C-x
+;;  p t' - use `C-x x t C-h' to see them.  In buffer `*Bookmark
+;;  List*', commands pertaining to tags are on prefix key `T' - use `T
+;;  C-h' to see them.  And remember that you can use `C-h >' to
+;;  describe all of the marked bookmarks, in the current sort order.
+;;  The bookmark descriptions include the tags.
+;;
+;;  When combined with other Bookmark+ commands (e.g. search,
+;;  query-replace) that apply to the marked bookmarks in the
+;;  `*Bookmark List*' window, you can really do quite a lot using
+;;  bookmark tags.  Use your imagination!
+;;
+;;  See Also:
+;;
+;;  * (@> "Bookmark Records: What A Bookmark Looks Like")
+;;  * (@> "Bookmarking the Marked Files in Dired")
+;;  * (@> "Opening Bookmarks Using Windows File Associations")
+;;  * (@> "Tag Commands and Keys")
+;;
+;;
+;;(@* "Bookmark Tags Can Have Values")
+;;  *** Bookmark Tags Can Have Values ***
+;;
+;;  Bookmark tags are simply names (strings) when you create them.
+;;  Nearly all of the predefined operations that use tags use these
+;;  names: sorting, marking, jumping, and so on.  But you can in fact
+;;  add an associated value to any tag.  This means that a tag can act
+;;  just like an object attribute or property: it can be a name/value
+;;  pair.
+;;
+;;  To add a value to a tag that has none, or to change the current
+;;  value of a tag, you use command `bmkp-set-tag-value', which is
+;;  bound to `T v' in the bookmark list and bound to `C-x x t v'
+;;  globally.  You are prompted for the bookmark, the tag, and the new
+;;  value.
+;;
+;;  A tag value can be a number, symbol, string, list, vector, and so
+;;  on.  It can be as complex as you like.  It can be any Emacs-Lisp
+;;  object that has read syntax, that is, that is readable by the Lisp
+;;  reader.  (Everything that is saved as part of a bookmark must be
+;;  readable; otherwise, your bookmark file could not be read
+;;  (loaded).)
+;;
+;;  Because tag values can be pretty much anything, you are pretty
+;;  much on your own when it comes to making use of them.  Bookmark+
+;;  does not provide predefined functions for using tag values.  In
+;;  general, tag values are something you will use with home-grown
+;;  Lisp code for your own purposes.
+;;
+;;  However, you can easily make some interactive use of tag values
+;;  with little effort.  You can, for example, define a predicate that
+;;  tests whether a bookmark has a tag value that satisfies some
+;;  property (e.g. is a number greater than 3.14159265358979), and
+;;  then you can use command `bmkp-bmenu-mark-bookmarks-satisfying' to
+;;  mark those bookmarks.
+;;
+;;  Tags that have the prefix "bmkp-" are reserved - do not name your
+;;  own tags using this prefix.
+;;
+;;  Currently, "bmkp-jump" is the only predefined bookmark tag.  You
+;;  can give this tag a value that is a function - it is called
+;;  whenever the tagged bookmark is visited.  Any Lisp-readable
+;;  function value is allowed: a symbol or a lambda expression.
+;;
+;;  For example, to display `Hello!' when a bookmark is visited you
+;;  can use this:
+;;
+;;    T v bmkp-jump RET (lambda () (message "Hello!"))
+;;
+;;  The function that is the value of a "bmkp-jump" tag is called just
+;;  after the the standard hook `bookmark-after-jump-hook' is invoked.
+;;  You can use this tag to invoke functions that are specific to
+;;  individual bookmarks; bookmarks can thus have their own, extra
+;;  jump functions.
+;;
+;;
+;;(@* "Hierarchical Structures of Bookmarks?")
+;;  *** Hierarchical Structures of Bookmarks? ***
+;;
+;;  You can use tags to organize sets of bookmarks in various ways.
+;;  But what about a simple, hierarchical (tree-shaped) structure like
+;;  the one that you use for bookmarks in a web browser?  You can get
+;;  a similar effect with Bookmark+ by just using a tag-naming
+;;  convention such as this:
+;;
+;;  vacation/
+;;  vacation/2017/
+;;  vacation/2017/winter/
+;;  vacation/2017/winter/photos/
+;;  vacation/2017/summer/
+;;  vacation/2017/summer/photos/
+;;  vacation/2018/
+;;  ...
+;;
+;;  You need not tag any bookmarks with any particular part of such a
+;;  pseudo-hierarchy.  For example, you might tag some bookmarks with
+;;  vacation/2017/winter/ and some with vacation/2017/winter/photos/,
+;;  without bothering to have any that are tagged with just vacation/
+;;  or just vacation/2017/.
+;;
+;;  You are not limited to a single tree.  You can have a tag such as
+;;  vacation/2017/winter/ and a tag such as work/projects/2017/alpha/,
+;;  without any need for those to have a common ancestor.
+;;
+;;  How can you use such a tagging scheme?
+;;
+;;  When you jump to a bookmark using a command that asks for tags,
+;;  such as `C-x j t +' (`bmkp-some-tags-jump'), you can use
+;;  completion.  So you can, for example, type `vac TAB' to show all
+;;  of your vacation tags (in `*Completions*'), and drill down,
+;;  completing more, to pick whichever particular vacation tag you're
+;;  interested in.  This is similar to traversing a web-browser
+;;  tree-like bookmarks menu.  But jump commands that use tags let you
+;;  match any number of tags at the same time, not just one.
+;;
+;;  Completion against the set of existing tags is also available when
+;;  you add tags to a bookmark.  And if option
+;;  `bmkp-prompt-for-tags-flag' is non-`nil' then you are prompted to
+;;  add tags whenever you create or update a bookmark.  But unlike the
+;;  case for web-browser bookmark creation, classifying a bookmark
+;;  when you create it or update it is optional.  You can always add
+;;  tags later, or not at all.
+;;
+;;  Such a purely conventional, pseudo-hierarchy might sound like a
+;;  silly hack, but it is at least as quick to use as is adding a
+;;  bookmark to your tree of browser bookmarks.  And it is more
+;;  useful, because the organization is more flexible and you can have
+;;  multiple, independent hierarchies.
+;;
+;;  The tagging scheme just described can help you keep track of
+;;  things, even though it is very simple.  There is nothing special
+;;  about it.  You might come up with other conventions for
+;;  classifying tags, which you find more convenient or more powerful.
+;;  And remember that tags can be more than just names.  They give you
+;;  the full power of Lisp values - do with them whatever you like.
+ 
+;;(@* "Function, Sequence, Variable-List,... Bookmarks")
+;;  ** Function, Sequence, Variable-List,... Bookmarks **
+;;
+;;  Bookmarks are typically thought of only as recorded locations.
+;;  Invoking a bookmark, called "jumping" to it, traditionally means
+;;  just visiting its location.  Bookmark+ looks at bookmarks in a
+;;  more general way than that.  A bookmark is a shortcut of some kind
+;;  - nothing more.  It is typically persistent, but it need not be
+;;  (see (@> "Temporary Bookmarks")).
+;;
+;;  A given type of bookmark is defined by its handler function, which
+;;  can do anything you like.  We've already seen the examples of
+;;  region bookmarks, which restore the active region, and Dired
+;;  bookmarks, which restore Dired markings, switches, inserted
+;;  subdirectories, and hidden (sub)directories.
+;;
+;;  A "function bookmark" simply invokes some function - any function.
+;;  You can, for instance, define a window or frame configuration and
+;;  record the configuration as a bookmark.  Then jump to the bookmark
+;;  to switch contexts.  (You can also bookmark a desktop and jump to
+;;  that.)
+;;
+;;  Function bookmarks might not seem too interesting, since there are
+;;  other ways to invoke functions in Emacs.  But the other features
+;;  of Bookmark+ combine with this feature.  You can, for instance,
+;;  tag function bookmarks.
+;;
+;;  And you can combine them, invoking the functions sequentially.
+;;  This is a particular case of using a "sequence bookmark", which
+;;  simply records a sequence of bookmarks.  The bookmarks in a
+;;  sequence can be of any kind, including other sequence bookmarks.
+;;
+;;  Command `bmkp-make-function-bookmark' (`C-x x c F') creates a
+;;  function bookmark - you give it a function symbol or a lambda
+;;  expression.
+;;
+;;  A function bookmark can invoke a keyboard macro instead of a
+;;  function.  With a prefix argument, `bmkp-make-function-bookmark'
+;;  creates a function bookmark from the last keyboard macro.  Jumping
+;;  to the bookmark executes the keyboard macro.  A bookmark is thus
+;;  one way to make a keyboard macro persistent.
+;;
+;;  If you provide a prefix argument to the bookmark jump command or
+;;  key that invokes a function bookmark, it is passed along to the
+;;  function.  If the bookmark invokes a keyboard macro then the
+;;  prefix argument determines how many times the macro is invoked.
+;;
+;;  The most general way to create or update a sequence bookmark is
+;;  using command `bmkp-set-sequence-bookmark' (`C-x x c s').  You are
+;;  prompted for the sequence bookmark name and the names of the
+;;  bookmarks that form its sequence and are thus invoked by it
+;;  sequentially.
+;;
+;;  If the sequence bookmark already exists then a prefix argument
+;;  determines whether the bookmarks you name are added to the
+;;  existing sequence or replace it, and if added, whether before or
+;;  after the bookmarks already in the sequence.
+;;
+;;  Command `bmkp-wrap-bookmark-with-last-kbd-macro' (`C-x x c C-k')
+;;  returns a sequence bookmark that invokes a bookmark you name and
+;;  then invokes the last keyboard macro.  You are prompted for the
+;;  names of both bookmarks.  If the sequence bookmark does not yet
+;;  exist then it is created.  (The bookmark to be added to the
+;;  sequence need not exist yet, and it is not created by adding its
+;;  name to the sequence.)
+;;
+;;  If you enter the same name for the sequence bookmark and the
+;;  bookmark to wrap with the keyboard macro, then the macro is simply
+;;  added to that (sequence) bookmark.
+;;
+;;  For example, if you enter `my-seq' for both of the
+;;  `bmkp-wrap-bookmark-with-last-kbd-macro' prompts, then the last
+;;  keyboard macro is added to sequence bookmark `my-seq'. Bookmark
+;;  `my-seq' need not exist yet, in which case it is created, with the
+;;  keyboard macro as its only member bookmark.
+;;
+;;  If the bookmark to add to the sequence is itself a different
+;;  (existing) sequence bookmark, then its member bookmarks are added
+;;  to the sequence being updated (or created), either before or after
+;;  its existing members, according to the prefix arg (which is passed
+;;  to `bmkp-set-sequence-bookmark').
+;;
+;;  Command `bmkp-bmenu-make-sequence-from-marked' creates a sequence
+;;  bookmark from the marked bookmarks in the bookmark-list display,
+;;  in their current order.
+;;
+;;  If you use library `Dired+' (`dired+.el') then you can use command
+;;  `diredp-do-bookmark-dirs-recursive' to create a Dired bookmark for
+;;  the current Dired buffer and each of its marked subdirectories.
+;;  Each of those subdirectories is handled similarly, and so on,
+;;  recursively.  This command also creates a sequence bookmark that
+;;  includes all of these Dired bookmarks, so that it represents a
+;;  tree (hierarchy) of Dired buffers that are opened together.  This
+;;  provides an alternative to inserting all of the relevant
+;;  subdirectories into the same Dired buffer.  With a prefix arg, all
+;;  of the descendent Dired buffers are included, whether or not they
+;;  are marked.
+;;
+;;  You can also create a function bookmark directly from a keyboard
+;;  macro, using command `bmkp-set-kmacro-bookmark'.  And you can save
+;;  the current set of keyboard macros as a bookmark, using command
+;;  `bmkp-set-kmacro-list-bookmark' - jumping to it restores all of
+;;  the macros'.
+;;
+;;  A variable-list bookmark saves and restores the values of a set of
+;;  variables.  Command `bmkp-set-variable-list-bookmark' prompts you
+;;  for the variables to include in the list and then sets the
+;;  bookmark.  Command `bmkp-jump-variable-list' (`C-x j v') restores
+;;  the recorded variable values for the bookmark's buffer.  You can
+;;  also create variable-list bookmarks non-interactively, using
+;;  function `bmkp-create-variable-list-bookmark'.
+;;
+;;  If you use library `zones.el', then you can move among multiple
+;;  restrictions (narrowings) in a buffer.  The restrictions are
+;;  stored in buffer-local variable `zz-izones'.  Command
+;;  `bmkp-set-izones-bookmark' bookmarks this value for the current
+;;  buffer.  Jumping to such a bookmark restores the saved ring/stack
+;;  of restrictions.
+;;
+;;
+;;(@* "Little Persistent Named Nothings")
+;;  *** Little Persistent Named Nothings ***
+;;
+;;  OK, so a bookmark need not "go" anywhere.  Function, sequence,
+;;  variable-list, and some other kinds of bookmarks have no real
+;;  "location" to move to or restore.  But the bookmarks talked about
+;;  so far at least have an associated action: you can "jump" to them,
+;;  even if "jump" can mean a arbitrary action that might have nothing
+;;  to do with reaching a destination.
+;;
+;;  You can also have a *non-invokable* bookmark, that is, one that
+;;  you cannot jump to.  This is a bookmark whose handler is the
+;;  function `ignore', which does nothing.
+;;
+;;  What's the point of that?  To record something persistently,
+;;  without needing to manage the file(s) you record it in, and to be
+;;  able to access that something by name.
+;;
+;;  As an example, library Isearch+ provides one such use case.  It
+;;  lets you interactively add, modify, and remove Isearch filter
+;;  predicates on the fly, providing more power and flexibility in
+;;  searching.
+;;
+;;  (A filter predicate is a function that accepts the current
+;;  search-hit limits as arguments.  If it returns `nil' then that
+;;  search hit is excluded from searching; otherwise it is included.)
+;;
+;;  You can also, on the fly, encapsulate the current suite of filter
+;;  predicates as a new filter predicate.  That is, you can manipulate
+;;  a complex sequence of filters as a single predicate, using a
+;;  simple name.  And you can save the definition of that new
+;;  predicate in a file, so you can use it again in future Emacs
+;;  sessions.
+;;
+;;  Alternatively, you can just bookmark the search predicate.  The
+;;  data saved in the bookmark is the suite of filters that is the
+;;  advised value of `isearch-filter-predicate' at the time of
+;;  bookmarking.
+;;
+;;  Then, in a future Emacs session, while Isearching you can hit a
+;;  key and enter the bookmark name (with completion), to apply that
+;;  suite of filters again.
+;;
+;;  Bookmarking is easier than defining a new predicate and bothering
+;;  with a file to save it in.  This is the kind of thing that
+;;  bookmarks are for: persistently saving named bits of data for
+;;  later retrieval by name.
+;;
+;;  Because the saved data in this case (the filter definition) has no
+;;  use outside the context of searching, there is no way to invoke it
+;;  - no jump action.  Its handler is `ignore'.
+;;
+;;  You can apply all Bookmark+ features to non-invokable bookmarks:
+;;  sort, edit, tag - whatever.  Use Bookmark+ to organize them, even
+;;  if you cannot invoke them.
+;;
+;;  Non-invokable bookmarks are shown using face `bmkp-no-jump' in the
+;;  bookmark-list display.
+;;
+;;  It is also possible for a bookmark to have a handler other than
+;;  `ignore', so that it is invokable, but that its jump action is
+;;  appropriate only in certain contexts.  This is the case, for
+;;  instance, for an Icicles search-hits bookmark.  You cannot invoke
+;;  it outside the context of Icicles searching.  For this reason,
+;;  these bookmarks are also shown with face `bmkp-no-jump' in the
+;;  bookmark-list display.
+ 
+;;(@* "Editing Bookmarks")
+;;  ** Editing Bookmarks **
+;;
+;;  In vanilla Emacs, you can edit the annotation associated with a
+;;  bookmark.  And you can rename a bookmark.  But that is all.  There
+;;  is no easy way to really edit a bookmark.
+;;
+;;  With Bookmark+:
+;;
+;;  * You can use `r' in the bookmark-list display (or `C-x x r'
+;;    elsewhere) to edit the name and the target file name (bookmarked
+;;    location) of a bookmark.  You are prompted for the new names.
+;;
+;;  * You can use `e' in the bookmark-list display (or `C-x x E'
+;;    elsewhere) to edit a complete bookmark - all of its information.
+;;    You edit the internal Lisp sexp that represents the bookmark
+;;    record.  This is the same internal definition that you see when
+;;    you use `C-u C-h RET' in the bookmark list.
+;;
+;;  * You can use `E' in the bookmark-list display to edit the
+;;    bookmark records of all of the marked bookmarks.  Again, this
+;;    means editing their internal Lisp sexps.  In particular, this
+;;    gives you an easy way to edit tags across multiple bookmarks.
+;;    All of the editing power of Emacs is available.
+;;
+;;  * You can use `T e' in the bookmark list (or `C-x x t e'
+;;    elsewhere), to edit a bookmark's tags.
+;;
+;;  For all but the first of these, you are placed in a separate
+;;  editing buffer.  Use `C-c C-c' when you are done editing, to save
+;;  your changes.  (To cancel, just kill the buffer: `C-x k'.)
+;;
+;;  You can also clone (duplicate) a bookmark, using `M-n', and then
+;;  edit any parts of it (e.g. using `e').  By default, the clone has
+;;  the same name, but with "<2>" appended.  With a prefix arg you are
+;;  prompted for the name.  Outside of the bookmark list you can use
+;;  `C-x x 2' to clone a bookmark.
+;;
+;;  There are many more keys and commands for editing bookmark tags.
+;;  You can copy tags (`C-x x t c') from one bookmark and paste them
+;;  to others, either replacing the original tags (`C-x x t C-y') or
+;;  adding to them (`C-x x t q').  You can be prompted for some tags
+;;  to add (`T +') or remove (`T -') from a bookmark.  You can delete
+;;  a tag from all bookmarks (`T d').  You can rename a tag everywhere
+;;  (`T r').  And you can set a tag's value.
+;;
+;;  As usual, all such commands are also available on the Bookmark+
+;;  menus.  The menus provide quick reminders of the available keys,
+;;  as does the help from `?' in the bookmark-list display.
+;;
+;;
+;;(@* "Bookmark Records: What A Bookmark Looks Like")
+;;  *** Bookmark Records: What A Bookmark Looks Like ***
+;;
+;;  It's worth dispelling some of the mystery about what a bookmark is
+;;  by mentioning what it looks like.  This can help when you edit a
+;;  bookmark record.  The first thing to mention is that the basic
+;;  structure of a bookmark record is described in the doc string of
+;;  variable `bookmark-alist' - but I'll repeat some of that info
+;;  here.
+;;
+;;  A bookmark record is nothing more than a list whose first element
+;;  is a string, the bookmark name.  The other list elements are
+;;  properties: key+value pairs that define the bookmark data.  Each
+;;  such pair is a cons: a nonempty list or a dotted list.
+;;
+;;  The car of the property is its name (a Lisp symbol).  The cdr is
+;;  its value.  What the value can be depends on the property - in
+;;  general it can be any Lisp value (number, string, list, symbol,
+;;  etc.).  A property with a null cdr means the same thing as having
+;;  no such property present.  For example, having the empty property
+;;  `(tags)' is the same as having no `tags' property at all.
+;;
+;;  There is nothing more to it: properties can be anything you like,
+;;  provided you provide some code to recognize them and do something
+;;  with them.
+;;
+;;  Of course, the types of properties you use most (maybe always) are
+;;  predefined, and the vanilla `bookmark.el' code and the Bookmark+
+;;  code recognize and use them.  The most important and most typical
+;;  property is this: `(filename . "/some/file/name.txt")', that is, a
+;;  cons whose car is the symbol `filename' and whose cdr is the name
+;;  (a string) of the bookmarked file.
+;;
+;;  With that in mind, you can see that renaming a bookmark just means
+;;  changing the string that is its car.  And relocating a bookmark
+;;  just means changing the string that is its `filename' - e.g., from
+;;  `(filename . "/home/foo.el")' to `(filename . "/some/other.xml")'.
+;;
+;;  If you already have a bookmark file, typically `~/.emacs.bmk',
+;;  take a look at the bookmark records in it.  A typical bookmark
+;;  also has these properties, in addition to `filename': `position',
+;;  `front-context-string', and `rear-context-string'.  You can guess
+;;  what they are - if not, see the doc string of `bookmark-alist'.
+;;
+;;  A Bookmark+ bookmark typically has some additional properties that
+;;  you can also guess.  Properties `time' and `visits' are updated
+;;  automatically each time you access the bookmark.
+;;
+;;  Some bookmarks have a `handler' property whose value is a function
+;;  that "jumps" to the bookmark "location".  I put those two terms in
+;;  quotes here because a handler is really just any function - it can
+;;  do anything you like, and there need not be any associated
+;;  location.
+;;
+;;  Some Bookmark+ bookmarks, including autofile bookmarks, just
+;;  "jump" to a file.  The position in the file is unimportant, and
+;;  "jumping" does not necessarily mean visiting the file with Emacs.
+;;  In effect, such bookmarks are just wrappers around the file,
+;;  letting you get the advantage of Bookmark+ features (tags etc.)
+;;  for a file.  Such bookmarks, which you can create using `C-x x c
+;;  a' or `C-x x c f', contain a `file-handler' property instead of a
+;;  `handler' property.  The difference between the two is that the
+;;  `file-handler' value is a function (Lisp function or shell
+;;  command) to be applied to the file, not to the bookmark.
+;;
+;;  Remember: A bookmark is just a persistent bit of information,
+;;  typically meta-information about a file and a position in that
+;;  file.
+;;
+;;  I'm mentioning all of this to make the point that you cannot
+;;  really hurt anything if you edit a bookmark record and you mess
+;;  things up.  The worst you can do is mess up all of your bookmarks
+;;  by making the file unreadable as Lisp data.  (It's always a good
+;;  idea to back up your bookmark file from time to time.)
+;;
+;;  And if each bookmark record after you edit it is a cons with a
+;;  string car then your bookmarks are generally OK, even if you might
+;;  have ruined the details of one or two of them.  Suppose you
+;;  somehow mistakenly delete the `a' in a `filename' property, for
+;;  instance.  No big deal - that bookmark no longer has a
+;;  recognizable target location, but the other bookmarks are still
+;;  OK.
+;;
+;;  The most important property for Bookmark+ users (aside from
+;;  `filename') is probably `tags'.  Its value (the cdr) is a list of
+;;  strings or conses - the bookmark's tags.  When you create a tag,
+;;  it is typically a string (just its name) - e.g. "blue".  If you
+;;  then give it a value as well, it becomes a cons with that string
+;;  (the name) as car and the value as cdr - e.g. `("blue" . 42)' or
+;;  `("blue" moonbeam 42)' - here the cdr is the list `(moonbeam 42)'.
+;;  Here is an example of a `tags' property: `(tags "hegel" ("blue"
+;;  . honeypot) "darwin")'.  Most of the time you will use strings as
+;;  tags.  See also (@> "Bookmark Tags Can Have Values").
+;;
+;;  When you edit bookmark records, just try to stay away from
+;;  changing any properties that you are not familiar with.  And make
+;;  sure that when you're done you have a proper Lisp list (open
+;;  parens closed etc.).  If you've never played with Lisp before, do
+;;  not panic.
+;;
+;;  Be aware if you see dots (`.') that they are important, and they
+;;  must be surrounded by whitespace: ` . '.  The amount of whitespace
+;;  never matters in Lisp (except inside a string etc.).
+;;
+;;  Such a dot just separates the car of a cons from its cdr.  (What's
+;;  a cons?  Just a car with a cdr!)  If the cdr is a list then we
+;;  typically drop the dot and the list's parens: We write `(b)'
+;;  instead of `(b . ())' and `(a b)' instead of `(a . (b))' or `(a
+;;  . (b . ()))'.
+;;
+;;  Finally, remember that when you set an existing bookmark again,
+;;  e.g., you use `C-x r m' and provide the name of an existing
+;;  bookmark, the existing properties are generally lost.  Some are
+;;  automatically updated.  Any that you might have added by editing
+;;  are lost, and any that are provided by default by the bookmark
+;;  handler are replaced.  The only exceptions to this are the
+;;  properties listed in option `bmkp-properties-to-keep', which by
+;;  default means properties `tags' and `annotation'.  Any existing
+;;  tags and annotation are preserved when you update a bookmark.
+ 
+;;(@* "Bookmark-List Views - Saving and Restoring State")
+;;  ** Bookmark-List Views - Saving and Restoring State **
+;;
+;;  The bookmark list (buffer `*Bookmark List*') provides a view into
+;;  the set of bookmarks.  You can mark, sort, and hide (filter, omit)
+;;  bookmarks - see (@> "The Bookmark List Display").  The state of
+;;  the displayed bookmark list can thus change.
+;;
+;;  At different times, and in different contexts, different views can
+;;  be useful.  Bookmark+ lets you save the current state of the
+;;  displayed list and later restore it.  There are a couple of
+;;  different ways to do this.
+;;
+;;
+;;(@* "Quitting Saves the Bookmark-List State")
+;;  *** Quitting Saves the Bookmark-List State ***
+;;
+;;  If option `bmkp-bmenu-state-file' is non-`nil', which it is by
+;;  default, then Bookmark+ remembers the last state of the bookmark
+;;  list when you quit it or you quit Emacs, and it restores that
+;;  state when you show the list again (which could be in the next
+;;  Emacs session).  You can think of this feature as your "Home" page
+;;  for bookmarks, giving you a stepping stone to the files and
+;;  directories you use most.
+;;
+;;  If, for example, when you quit the bookmark list you are showing
+;;  only bookmarks to Info nodes and UNIX manual pages, sorted in a
+;;  particular way, and with some of them marked with `>' for
+;;  particular processing, then the next time you open the list the
+;;  same state is restored: the same set of bookmarks is shown, in the
+;;  same order, with the same markings.  Deletion flags (`D') and
+;;  modification indicators (`*') are purposefully not saved as part
+;;  of the display state - they are lost when you quit the display.
+;;
+;;  You can turn off this automatic bookmark-list display state
+;;  saving, if you want, by customizing option `bmkp-bmenu-state-file'
+;;  to `nil'.  And you can toggle this option at any time, using
+;;  `C-M-~' in the bookmark list (command
+;;  `bmkp-toggle-saving-menu-list-state').  In particular, if you want
+;;  your next visit to the bookmark list to start out with a
+;;  previously recorded state instead of the current state, just hit
+;;  `C-M-~' before quitting the bookmark list.
+;;
+;;
+;;(@* "State-Restoring Commands and Bookmarks")
+;;  *** State-Restoring Commands and Bookmarks ***
+;;
+;;  In addition to automatically saving/restoring the final
+;;  bookmark-list display state, you can save this state at any time,
+;;  any number of times, for later restoration.  This gives you the
+;;  ability to create multiple persistent views of your bookmarks.
+;;
+;;  There are two ways to do this:
+;;
+;;  * Create a bookmark for the `*Bookmark List*' buffer itself: a
+;;    bookmark-list bookmark.
+;;
+;;  * Define a command that restores the bookmark-list state.
+;;
+;;  When you use `C-x r m' (`bmkp-bookmark-set-confirm-overwrite') in
+;;  buffer `*Bookmark List*' to create a bookmark-list bookmark, the
+;;  current sort order, filter, regexp pattern, title, and omit list
+;;  are saved as part of the bookmark.  (These concepts are described
+;;  below - see (@> "Bookmark List Display").)  Jumping to such a
+;;  bookmark restores all of these.
+;;
+;;  Alternatively, you can define a command that does the same thing,
+;;  but without creating another bookmark - use `C-c C-c'
+;;  (`bmkp-bmenu-define-command') in the bookmark list to do this.
+;;  You are prompted for the name of the new command.  Use the command
+;;  anytime (including in another Emacs session) to restore the
+;;  bookmark list.
+;;
+;;  Define any number of such commands for the views you use.  The
+;;  file for saving the definitions (see option
+;;  `bmkp-bmenu-commands-file') is never overwritten, so you can also
+;;  add other code to it manually, if you want.  The file is read the
+;;  first time the bookmark list is displayed in a given Emacs
+;;  session.
+;;
+;;  The state that is saved and restored using a bookmark-list
+;;  bookmark or a command defined using `C-c C-c' is only a partial
+;;  state.  The current set of markings and some other information are
+;;  not saved, in order to save disk space and save/restore time.
+;;
+;;  Sometimes, however, you really want to save the entire
+;;  bookmark-list state, creating a full snapshot.  You can use `C-c
+;;  C-C' (aka `C-c C-S-c', `bmkp-bmenu-define-full-snapshot-command')
+;;  to do that.  This defines a command that restores the bookmark
+;;  list completely.  That is the same thing that happens
+;;  automatically (by default) whenever you quit the bookmark list (or
+;;  Emacs), but defining snapshot commands lets you have multiple
+;;  saved states and switch to them at will.
+;;
+;;  Be aware, however, that full-snapshot command definitions can be
+;;  quite large, since they each contain a copy of the current
+;;  bookmark list and any accessory lists (hidden and marked bookmarks
+;;  etc.).
+;;
+;;  Whether you use `C-c C-c' or `C-c C-C' to define a state-restoring
+;;  command or you create a bookmark-list bookmark, you can create a
+;;  sequence bookmark that combines such bookmark-list restoration
+;;  with activation of other bookmarks.  (To include a state-restoring
+;;  command in a sequence, you need to first create a function
+;;  bookmark that uses the command, and then include that bookmark in
+;;  the sequence.)
+ 
+;;(@* "Bookmarking without Visiting the Target")
+;;  ** Bookmarking without Visiting the Target **
+;;
+;;  There are several use cases for bookmarking a target without
+;;  visiting it:
+;;
+;;  1. In an Emacs buffer you come across a reference or a link to a
+;;     file or a URL.  You bookmark the target without bothering to
+;;     visit it first.  You do not really care which position in the
+;;     file is bookmarked.
+;;
+;;  2. In Dired, you mark certain files and then bookmark all (each)
+;;     of them, in one operation.
+;;
+;;  3. In a compilation buffer (e.g. `*grep*', `*compile*') or an
+;;     occur or multi-occur buffer (`*Occur*'), you bookmark one or
+;;     more of the hits.  Such a bookmark takes you to the appropriate
+;;     position in the target file or buffer.
+;;
+;;  4. You bookmark a file that you might not even be able to visit in
+;;     Emacs (in the sense of editing it in a buffer) - for example, a
+;;     music file.  "Jumping" to the bookmark performs an operation
+;;     appropriate to the file - for example, playing music.
+;;
+;; 
+;;(@* "Bookmarking a File or a URL")
+;;  *** Bookmarking a File or a URL ***
+;;
+;;  You can use commands `bmkp-file-target-set' and
+;;  `bmkp-url-target-set', bound by default to `C-x x c f' and `C-x x
+;;  c u', to bookmark any file or URL.  Completion is available, the
+;;  default file name or URL being determined by the text at point.
+;;  In addition to the file or URL, you are prompted for the bookmark
+;;  name.  (In general, the keys `f' and `u' are used in key sequences
+;;  for file and URL bookmarks, respectively.)
+;;
+;;  
+;;(@* "Bookmarking the Marked Files in Dired")
+;;  *** Bookmarking the Marked Files in Dired ***
+;;
+;;  If you use `Dired+' (library `dired+.el'), then you can bookmark
+;;  all of the marked files (and subdirectories) in a Dired buffer at
+;;  once, as autofiles, even if you normally do not or cannot visit
+;;  those files in Emacs.  These keys are available in Dired:
+;;
+;;    `M-b'                   - Bookmark each marked file
+;;    `C-M-S-b' (aka `C-M-B') - Bookmark each marked file in a
+;;                              bookmark-file that you specify
+;;    `C-M-b'                 - Bookmark each marked file in a
+;;                              bookmark-file you specify, and create
+;;                              a bookmark for that bookmark-file
+;;
+;;  Each of these commands bookmarks each of the marked files and
+;;  subdirectories as an autofile.  By default, the bookmark file used
+;;  for the latter two commands is in the current directory.
+;;
+;;  If you use multiple `C-u' as a prefix arg for these commands, then
+;;  you can bookmark all of the files in Dired, regardless of
+;;  markings, as follows:
+;;
+;;    `C-u C-u'         - Use all files in Dired, except directories
+;;    `C-u C-u C-u'     - Use all files and dirs, except `.' and `..'
+;;    `C-u C-u C-u C-u' - Use all files and all directories
+;;
+;;  `C-M-b' not only bookmarks each of the marked files, it also
+;;  creates a bookmark-file bookmark for that set of bookmarks.  See
+;;  (@> "Bookmark-File Bookmarks"), below.
+;;
+;;  You can later "jump" to that bookmark to load its set of
+;;  bookmarks.  If you use `C-u' when you jump to it, then you switch
+;;  bookmark files, so that `C-x x e' (or `C-x r l') displays only the
+;;  bookmarks created from the marked files.  Without `C-u', jumping
+;;  to the bookmark-file bookmark simply loads its bookmarks into the
+;;  current set of bookmarks.
+;;
+;;  
+;;(@* "Bookmarking Compilation, Grep, and Occur Hits")
+;;  *** Bookmarking Compilation, Grep, and Occur Hits ***
+;;
+;;  In a similar way, you can bookmark the file or buffer positions of
+;;  selected hits in a compilation buffer (including `*grep*') or an
+;;  `occur' or `multi-occur' buffer.
+;;
+;;  `C-c C-b' in such a buffer bookmarks the target of the hit at
+;;  point.  `C-c C-M-b' bookmarks the target of each hit in the
+;;  buffer.
+;;
+;;  `C-c C-M-b' in these buffers is thus similar to `M-b' in a Dired
+;;  buffer.  Unlike Dired, however, there is no way to mark such hits.
+;;  Every hit is bookmarked.
+;;
+;;  Nevertheless, you can get the same effect.  Just use `C-x C-q' to
+;;  make the buffer writable (e.g. temporarily), and then remove any
+;;  hits that you do not want to bookmark.  You can remove hits anyway
+;;  you like, including by `C-k' and by regexp (`M-x flush-lines' or
+;;  `M-x keep-lines').
+;;
+;;  See also: (@> "Autonamed Bookmarks - Easy Come Easy Go"),
+;;  bookmarking occur hits using autonamed bookmarks.
+;;
+;;
+;;(@* "Bookmarking Files That You Cannot Visit with Emacs")
+;;  *** Bookmarking Files That You Cannot Visit with Emacs ***
+;;
+;;  You use lots of files that you never visit using Emacs, but that
+;;  you might like to keep track of or access in other ways: music
+;;  files, image files, whatever.
+;;
+;;  You can define a new kind of bookmark for any file type you are
+;;  interested in, implementing a bookmark handler for it that
+;;  performs the appropriate action on it when you "jump" to it.  That
+;;  action needs to be expressible using an Emacs function, but it
+;;  need not have anything to do with visiting the file in Emacs.
+;;
+;;  When you bookmark a target file that Emacs recognizes as an image
+;;  or sound file, an appropriate handler is used automatically.
+;;
+;;  After you create individual bookmarks for, say, music or image
+;;  files, you can use `P B' in the bookmark-list display to show only
+;;  those bookmarks, and then use `C-x r m' to bookmark that state of
+;;  the bookmark-list.
+;;
+;;  That bookmark-list bookmark in effect becomes a music playlist or
+;;  an image library or slideshow.  Jump to it anytime you want to
+;;  listen to that set of music pieces or view those images.  And you
+;;  can use `C-x x B' and then `C-x x next' to cycle among the music
+;;  pieces or images (slideshow).  (See (@> "Cycling the Navigation List").)
+;;
+;;  Together with the use of bookmark tags, this gives you a handy way
+;;  to organize and access objects of any kind.  See (@> "Bookmark Tags").
+;;
+;;  You use option `bmkp-default-handlers-for-file-types' to control
+;;  which operation (handler) to use for which file type.  This is a
+;;  set of associations (an alist) with each key being a regexp
+;;  matching a file name, and with each associated value being a Lisp
+;;  sexp that evaluates to either a shell command (a string) or an
+;;  Emacs function (a symbol or lambda form).
+;;
+;;  You can think of `bmkp-default-handlers-for-file-types' as
+;;  somewhat analogous to `auto-mode-alist'.  But it maps file-name
+;;  patterns to file actions instead of mapping them to buffer modes.
+;;  And it has an effect only when you use certain commands.
+;;
+;;  The handler for the bookmark created invokes the shell command or
+;;  the Emacs function with the file name as argument.
+;;
+;;  Here is an example option value:
+;;
+;;   (("\\.ps$"    . "gsview32.exe")
+;;    ("\\.html?$" . browse-url)
+;;    ("\\.doc$"   . w32-browser))
+;;
+;;  This value causes creation of bookmarks that, when you jump to
+;;  them, invoke:
+;;
+;;   * shell command `gsview32.exe' on the bookmark's
+;;     target file if it is PostScript (extension `.ps')
+;;
+;;   * Emacs Lisp function `browse-url' on the file if it is HTML
+;;     (extension `.htm' or `.html')
+;;
+;;   * Emacs Lisp function `w32-browser' on the file if the file
+;;     extension is `.doc' (e.g., a Microsoft Word file)
+;;
+;;  The default value of `bmkp-default-handlers-for-file-types' is
+;;  taken from the value of option `dired-guess-shell-alist-user'
+;;  (from Dired X).
+;;
+;;  The associations are checked in order, and the first one that
+;;  matches the given file name is used.  You can thus order them to
+;;  deal with overlapping file-name patterns.
+;;
+;;  If no matching file association is found in
+;;  `bmkp-default-handlers-for-file-types', and if option
+;;  `bmkp-guess-default-handler-for-file-flag' is non-`nil' (it is
+;;  `nil' by default), then Bookmark+ will guess a shell command to
+;;  use.  It does this by matching the file name against
+;;  `dired-guess-shell-alist-default' (also from Dired X).  In Emacs
+;;  23 and later, if it finds no shell command that way then it
+;;  guesses one based on mailcap entries.
+;;
+;;  When a bookmark is created using `C-x x c f' or `C-x x c a' for a
+;;  file that matches `bmkp-default-handlers-for-file-types', the
+;;  shell command or Lisp function that "jumps to" (opens) the file is
+;;  saved in the bookmark as property `file-handler' (not `handler').
+;;
+;;
+;;(@* "Opening Bookmarks Using Windows File Associations")
+;;  *** Opening Bookmarks Using Windows File Associations ***
+;;
+;;  If you use Microsoft Windows there is no need to define new
+;;  bookmark types and handlers, if the action you want is the one
+;;  that Windows associates with the file.  You already have a set of
+;;  file/program associations, and Bookmark+ recognizes these as
+;;  alternative handlers.
+;;
+;;  You can thus take advantage of Windows file associations to open
+;;  bookmarks for files of all kinds.  To do this, you also need
+;;  library `w32-browser.el'.  In the bookmark list, the following
+;;  keys are bound to commands that open bookmarks using the
+;;  associated Windows `Open' applications:
+;;
+;;    `M-RET'     - `bmkp-bmenu-w32-open'
+;;    `M-mouse-2' - `bmkp-bmenu-w32-open-with-mouse'
+;;    `M-o'       - `bmkp-bmenu-w32-jump-to-marked'
+;;
+;;  Windows file associations are always available to you, in addition
+;;  to any other file associations that you define using
+;;  `bmkp-default-handlers-for-file-types' (see
+;;  (@> "Bookmarking Files That You Cannot Visit with Emacs")).
+;;
+;;  You can thus have two different programs associated with the same
+;;  kind of file.  Your MS Windows file association for PostScript
+;;  might, for example, use Adobe Distiller to create a PDF file from
+;;  PostScript, while your `bmkp-default-handlers-for-file-types'
+;;  association for PostScript might use GhostView to display it
+;;  directly.
+;;
+;;  Besides using `M-RET' etc. in buffer `*Bookmark List*', if in
+;;  `bmkp-default-handlers-for-file-types' you register `w32-browser'
+;;  as the association to use for a given file pattern, then you can
+;;  use command `bmkp-w32-browser-jump' (not bound, by default)
+;;  anywhere to open a bookmark whose file name matches that pattern,
+;;  using its Windows file-association program.
+;;
+;;  You can also specify `w32-browser' as the bookmark "type" when you
+;;  use command `bmkp-jump-to-type' (`C-x j :').  Either of these
+;;  approaches gives you a way to use completion to choose a bookmark
+;;  to open using a Windows file association.
+;;
+;;  Specifying such an association in
+;;  `bmkp-default-handlers-for-file-types' means that bookmarks for
+;;  such a file will have a `file-handler' value of `w32-browser', to
+;;  "jump" to (i.e., open) the file.
+;;
+;;  To set up a given file extension for use this way, add an entry
+;;  (REGEXP . w32-browser) to option
+;;  `bmkp-default-handlers-for-file-types', where REGEXP matches the
+;;  file extension.
+;;
+;;  For example, to make a command such as `bmkp-bookmark-a-file'
+;;  (`C-x x c a') automatically bookmark `*.doc' files using the
+;;  associated MS Windows program (typically MS Word), add this entry:
+;;  ("\\.doc$" . w32-browser).
+;;
+;;
+;;(@* "Autofile Bookmarks")
+;;  *** Autofile Bookmarks ***
+;;
+;;  An autofile bookmark, or just an autofile, is a bookmark to a file
+;;  or directory that uses the nondirectory part of its file name (or
+;;  of its `directory-file-name', if a directory name) as the bookmark
+;;  name.
+;;
+;;  You can look at an autofile bookmark as just a wrapper around a
+;;  file or directory: a way to attach meta information (such as tags)
+;;  to it.  But you can use an autofile bookmark much as you would use
+;;  a file or directory.
+;;
+;;  To create a new autofile bookmark, you can use
+;;  `bmkp-bookmark-a-file' (aka `bmkp-autofile-set'), which is bound
+;;  by default to `C-x x c a'.  (In general, the key `a' is used in
+;;  key sequences for autofile bookmarks.)
+;;
+;;  If user option `bmkp-propertize-bookmark-names-flag' is non-`nil',
+;;  which it is by default with Emacs 21 and later, then you can have
+;;  multiple bookmarks with the same name.  This is important for
+;;  autofile bookmarks because the bookmark name is only the
+;;  nondirectory part of the file name.  This Bookmark+ feature lets
+;;  you have different autofile bookmarks for files of the same name
+;;  in different directories.
+;;
+;;  In addition to the single autofile bookmark that you can create
+;;  for a given absolute file location, you can of course create
+;;  additional bookmarks to the same file or directory, using
+;;  different bookmark names.  Among other things, this lets you tag
+;;  the same file or directory in different ways.
+;;
+;;  You can use `C-x j a' (`bmkp-autofile-jump') or `C-x 4 j a'
+;;  (`bmkp-autofile-jump-other-window') to visit an autofile bookmark.
+;;  And there are commands for visiting an autofile that is tagged in
+;;  certain ways.  For example, `bmkp-autofile-some-tags-regexp-jump'
+;;  (`C-x j t a % +') jumps to an autofile bookmark that has at least
+;;  one tag matching a given regexp.  See (@> "Tagging Files").
+;;
+;;  You can create autofiles automatically whenever you use an Emacs
+;;  file-cache command, by customizing user option
+;;  `bmkp-autofile-filecache'.  See the Emacs manual, node `File Name
+;;  Cache'.
+;;
+;;  This optional bookmark creation can replace adding the file to the
+;;  cache, or it can be in addition to caching the file.  This is done
+;;  by advising command `file-cache-add-file', which means that it
+;;  affects also the other Emacs file-cache commands that use that
+;;  function, directly or indirectly:
+;;
+;;  * `file-cache-add-directory'
+;;  * `file-cache-add-directory-list'
+;;  * `file-cache-add-directory-recursively'
+;;  * `file-cache-add-directory-using-find'
+;;  * `file-cache-add-directory-using-locate'
+;;  * `file-cache-add-file-list'
+;;
+;;  See the Emacs manual, node `File Name Cache'.
+;;
+;;  If option `bmkp-autofile-access-invokes-bookmark-flag' is
+;;  non-`nil' then regular access of a file or directory
+;;  (e.g. `find-file') invokes the associated autofile bookmark, if
+;;  there is one.  This has the effect of updating the bookmark data,
+;;  such as the number of visits.  The default value of the option is
+;;  `nil'.  To set the option value, either use Customize
+;;  interactively or use a Customize function.
+;;
+;;  Finally, if you use libraries `Dired+' and `highlight.el' then
+;;  autofiles are highlighted specially in Dired, and the highlighting
+;;  indicates whether the file is tagged.
+;;
+;;
+;;(@* "A Type-Aware `find-file'")
+;;  *** A Type-Aware `find-file' ***
+;;
+;;  User option `bmkp-default-handlers-for-file-types' (see
+;;  (@> "Bookmarking Files That You Cannot Visit with Emacs")) gives
+;;  you a way to associate a file type, as determined by the file
+;;  name (typically its extension) with a default file action.  This
+;;  is like MS Windows file associations, but it is specific to Emacs
+;;  and Bookmark+.  And it is useful for more than just bookmarks.
+;;
+;;  Commands `bmkp-find-file' (`C-x j C-f') and
+;;  `bmkp-find-file-other-window' (`C-x 4 j C-f') take advantage of
+;;  this association to open files.  If a file name matches no pattern
+;;  in `bmkp-default-handlers-for-file-types' then these commands act
+;;  like `find-file' and `find-file-other-window'.  Otherwise, the
+;;  invoke the associated file handler in
+;;  `bmkp-default-handlers-for-file-types'.
+;;
+;;  Invoking the handler is just what the ordinary autofile jump
+;;  commands (e.g. `C-x j a') do.  But `bmkp-find-file' is different
+;;  in a couple of ways.
+;;
+;;  Like vanilla `find-file' (`C-x C-f'), `C-x j C-f' and `C-x 4 j
+;;  C-f' use `read-file-name' to prompt you for the file name.  The
+;;  completion candidates are the names of all of the files in the
+;;  current directory (`default-directory'), that is, the directory of
+;;  your current minibuffer input.  This includes the names of any
+;;  autofile bookmarks in the same directory.  And like `C-x C-f' you
+;;  can change directory, navigating up and down the file hierarchy.
+;;  In sum, these commands are file-aware.
+;;
+;;  The ordinary autofile jump commands on the other hand use
+;;  `completing-read' to complete your input against all autofile
+;;  bookmark names, regardless of directory.  And since the bookmark
+;;  names reflect only the relative file names, it is not so easy to
+;;  distinguish two autofiles with the same name but in different
+;;  directories.  (`Icicles' can help here, BTW.)
+;;
+;;  There is a `bmkp-find-file-' command that corresponds to each
+;;  `bmkp-autofile-' command.  For example,
+;;  `bmkp-find-file-some-tags-regexp' (`C-x j t C-f % +') corresponds
+;;  to `bmkp-autofile-some-tags-regexp-jump' (`C-x j t a % +').  All
+;;  `bmkp-find-file' commands use `C-f' in their key bindings, as a
+;;  reminder of their reading file names a la `find-file'.
+;;
+;;  But whereas `C-x j C-f' and `C-x 4 j C-f' let you access any file,
+;;  the other `bmkp-find-file-' commands, which find files that have
+;;  certain tags, provide only autofiles as completion candidates.
+;;  That's obvious, since files are tagged by bookmarking them.
+;;
+;;  You can thus use the `C-f' commands to take advantage of
+;;  file-action associations that you define.  But if you want to
+;;  associate metadata (e.g. tags) with files or directories, then you
+;;  will want to create autofiles.  You can do this when you invoke
+;;  these commands, by providing a prefix argument.  Thus, for
+;;  example, `C-u C-x j C-f foo.doc' opens file `foo.doc', respecting
+;;  any handler recorded for it via option
+;;  `bmkp-default-handlers-for-file-types' - but it also creates an
+;;  autofile bookmark for it.
+;;
+;;  Whenever an autofile bookmark is used, regardless of whether you
+;;  access it using a `bmkp-autofile*' command or a `bmkp-find-file*'
+;;  command, the full bookmark record (including handler) is taken
+;;  into account.
+;;
+;;  Note, however, that the `C-f' tag commands differ from the `a' tag
+;;  commands in how the completion candidates are filtered.
+;;
+;;  For the former, `read-file-name' is passed a predicate that is
+;;  applied to each file name in the directory, filtering out any such
+;;  candidates that do not satisfy it (e.g., do not have the required
+;;  tags).
+;;
+;;  This happens before you type any input to match the file name.
+;;  The predicate checks for a corresponding autofile and checks its
+;;  tags (depending on the command).  If there are lots of files in
+;;  the current directory, this can take a while.
+;;
+;;  For the latter, similar tests are made, but instead of testing
+;;  each file in the current directory, these commands test each
+;;  bookmark in the current bookmark list.  If there are lots of
+;;  bookmarks this can take a while.
+;;
+;;  In some cases a `C-f' command is quicker; in some cases a `a'
+;;  command is quicker.
+;;
+;;  If you use `Icicles', then the performance hit for `C-f' when
+;;  there are lots of files in a directory is greatly reduced.  This
+;;  is because `Icicles' applies the filtering predicate after, not
+;;  before, you type text in the minibuffer.  In other words, instead
+;;  of testing each file in the directory, it tests only the files
+;;  that match your input.  (In addition, if you use `Icicles' then
+;;  you get multi-command versions of each of these bookmark commands,
+;;  which means that you can visit more than one file per command
+;;  invocation.)
+ 
+;;(@* "Tagging Files")
+;;  ** Tagging Files **
+;;
+;;  Section (@> "Tags: Sets of Bookmarks") covers bookmark tags, which
+;;  are persistent metadata that you define to help you organize
+;;  bookmarks into meaningful sets.
+;;
+;;  Section (@> "Autofile Bookmarks") describes autofile bookmarks,
+;;  which, in effect, let you treat files and directories generally as
+;;  if they were bookmarks.  You can choose a file or directory to
+;;  visit or act on by its name and location, but also by its bookmark
+;;  metadata.
+;;
+;;  In particular, you can tag a file or directory - that is, specify
+;;  tags for its associated autofile bookmark.  And you can then visit
+;;  a file or directory that has a given set of tags.  Bookmark+
+;;  provides commands that automatically create and manipulate
+;;  autofile bookmarks, that is, bookmarks that have the same name as
+;;  the files or directories they tag.
+;;
+;;  Command `bmkp-tag-a-file' (aka `bmkp-autofile-add-tags'), bound by
+;;  default to `C-x x t + a', prompts you for a set of tags and a file
+;;  or directory, and creates or sets the corresponding autofile
+;;  bookmark.  Command `bmkp-untag-a-file' (aka
+;;  `bmkp-autofile-remove-tags'), bound by default to `C-x x t - a',
+;;  similarly lets you remove specified tags from a file or directory.
+;;
+;;  If you also use library `Icicles', then you can act on multiple
+;;  files and directories during the same command (a "multi-command").
+;;  You can thus all at once tag a set of files and directories the
+;;  same way, or act on a set of files and directories that are tagged
+;;  similarly.  `Icicles' also lets you create autofiles or add or
+;;  remove tags, on the fly, whenever you use commands (e.g. `C-x
+;;  C-f') that access files or directories.
+;;
+;;  If you also use library `Dired+' (`dired+.el') then you can use
+;;  `C-+' to add tags to the marked files and directories, and `C--'
+;;  to remove tags from them.  You can use `C-M-+' and `C-M--' to do
+;;  the same thing for the current file.  You can also use items from
+;;  the Dired menus to do these things.
+;;
+;;  Bookmark+ provides two kinds of command for visiting files
+;;  associated with bookmarks that have tags.
+;;
+;;  The first kind uses bookmarks directly: you choose a bookmark
+;;  name, not a file name, but the candidates are only file and
+;;  directory bookmarks.  These commands have the prefix `bmkp-file-'
+;;  or `bmkp-autofile-'.
+;;
+;;  As a special case, commands with the prefix `bmkp-file-this-dir-'
+;;  limit the choices to bookmarks for files and subdirectories of the
+;;  current directory.  By default, the commands across all
+;;  directories are on prefix key `C-x j t f', and those for the
+;;  current directory only are on prefix key `C-x j t .'.  See
+;;  (@> "Different Types of Jump Commands") for more about these
+;;  commands.
+;;
+;;  The second kind of command is for visiting tagged files, that is,
+;;  autofile bookmarks, just like the commands with prefix
+;;  `bmkp-autofile-'.  However, these commands do not handle the
+;;  bookmark as such, but only its associated file or directory.  They
+;;  recognize its tags, but they pay no attention to any special
+;;  handler or other recorded information.
+;;
+;;  These commands have the prefix `bmkp-find-file-', and they are on
+;;  the prefix key `C-x j t C-f'.  The `C-f' here is intended to
+;;  remind you of command `find-file' (`C-x C-f').  Like `find-file',
+;;  they use `read-file-name' to read the bookmark's file name,
+;;  instead of using `completing-read' to read the bookmark name.
+;;
+;;  Yes, for an autofile bookmark the bookmark name and the relative
+;;  file name are the same.  But `read-file-name' is file-aware, and
+;;  lets you browse up and down the directory hierarchy.
+;;
+;;  The `bmkp-find-file-' commands are available only for Emacs 22 and
+;;  later (because they use `read-file-name' with a PREDICATE
+;;  argument).
+;;
+;;  For example:
+;;
+;;    `C-x j t f   % +' is `bmkp-file-some-tags-regexp-jump'
+;;    `C-x j t .   % +' is `bmkp-file-this-dir-some-tags-regexp-jump'
+;;    `C-x j t a   % +' is `bmkp-autofile-some-tags-regexp-jump'
+;;    `C-x j t C-f % +' is `bmkp-find-file-some-tags-regexp'
+;;
+;;  * The first of these visits any file or directory bookmark that
+;;    has at least one tag among the tags you specify, and you choose
+;;    among bookmark names.  The file or directory can be anywhere.
+;;
+;;  * The second is similar to the first, but only bookmarks for files
+;;    in the current directory are completion candidates.
+;;
+;;  * The third is similar to the first, but only autofile bookmarks
+;;    are completion candidates.
+;;
+;;  * The fourth is similar to the third regarding tags, but it uses
+;;    `read-file-name', so you can browse up and down the file
+;;    hierarchy.  The completion candidates are file and directory
+;;    names, not bookmark names.
+;;
+;;  If you use `Icicles', there are similar sets of commands, but they
+;;  all let you act on multiple files and directories at the same time
+;;  (multi-commands).  For example, you can delete (or byte-compile
+;;  or...) a set of files and directories according to their tags.
+;;
+;;  Remember that you can create multiple bookmarks for the same file
+;;  or directory, providing them with different sets of tags.  (Only
+;;  one of the bookmarks is the autofile bookmark.)
+;;
+;;  You can also use multiple bookmark files (the files that record
+;;  bookmarks).  Different projects can thus have different tags for
+;;  the same sets of files and directories, even using just autofile
+;;  bookmarks.  See (@> "Using Multiple Bookmark Files").
+;;
+;;  A file or directory bookmark can have any number of tags, and
+;;  multiple such bookmarks can have the same tag.  You can sort,
+;;  show/hide, or mark files and directories based on their tags.
+ 
+;;(@* "Using Multiple Bookmark Files")
+;;  ** Using Multiple Bookmark Files **
+;;
+;;  Bookmark-list views (see
+;;  (@> "Bookmark-List Views - Saving and Restoring State")) provide
+;;  one way to switch among various sets of bookmarks that you use.
+;;  But that feature affects only the bookmarks that you see displayed
+;;  in buffer `*Bookmark List*', not the actual set of available
+;;  bookmarks.
+;;
+;;  The bookmarks available to you are defined in a bookmark file.  By
+;;  default, they are stored in the file named by option
+;;  `bmkp-last-as-first-bookmark-file', if non-`nil', otherwise in the
+;;  file named by option `bookmark-default-file' (`~/.emacs.bmk', by
+;;  default).
+;;
+;;  If you use only one bookmark file then you never need to load or
+;;  save it manually.  Emacs does that for you automatically.
+;;
+;;  But you can have multiple bookmark files if you want, and at any
+;;  time you can change the bookmark file that is current.  To do
+;;  that, use `C-x x L' (or just `L' in the bookmark-list display),
+;;  which is bound to command `bmkp-switch-bookmark-file-create'.
+;;  Having multiple bookmark files gives you an added degree of
+;;  flexibility.
+;;
+;;  By default, the last bookmark file you used, in your last Emacs
+;;  session, is the initial bookmark file that is loaded automatically
+;;  in your next session.  But if you prefer, you can make Bookmark+
+;;  always start with the same bookmark file
+;;  (`bookmark-default-file').  User option
+;;  `bmkp-last-as-first-bookmark-file' controls this.
+;;
+;;  You can easily see which bookmark file is current at any time: It
+;;  is shown at the top of buffer `*Bookmark List*', and it is near
+;;  the top of the help output from command
+;;  `bmkp-bmenu-mode-status-help', which is what is bound to `?' and
+;;  `C-h m' in buffer `*Bookmark List*'.
+;;
+;;  When you switch to another bookmark file, the default choice for
+;;  the file to switch to is the last bookmark file you used (in the
+;;  same session).  So it is trivial to toggle back and forth between
+;;  two bookmark files: just hit `RET' to accept the default.
+;;
+;;  When bookmarks are saved automatically, or when you save them
+;;  using `bookmark-save' (`S' in the bookmark-list display or `C-x x
+;;  s' globally) and you don't use a prefix argument, they are saved
+;;  in the current bookmark file.
+;;
+;;  You can turn off the automatic saving of the current bookmark
+;;  file, by customizing option `bookmark-save-flag' to `nil'.  And
+;;  you can toggle this option at any time, using `M-~' in the
+;;  bookmark list (command `bmkp-toggle-saving-bookmark-file').
+;;
+;;  Besides using multiple bookmark files as *alternatives*, you can
+;;  combine them, using them as component bookmark subsets (like
+;;  modules).  To do that, use command `C-x x l' (lowercase `l'),
+;;  which is bound to `bookmark-load', and do not use a prefix
+;;  argument.  (Using a prefix argument with `C-x x l' is the same as
+;;  using `C-x x L': it switches bookmark files.)  Here too the
+;;  default is the name of the last bookmark file that you used.
+;;
+;;  In the `*Bookmark List*' display you can use `M-l' to load all of
+;;  the bookmark files corresponding to the marked bookmark-file
+;;  bookmarks, in the order in which they are displayed.  Any non
+;;  bookmark-file bookmarks that are marked are ignored.  Before
+;;  loading, if any of your currently loaded bookmarks have been
+;;  modified then you are asked if you want to save them first, before
+;;  loading the others.
+;;
+;;  After loading, to avoid confusion and possible mistakes, automatic
+;;  saving to the current bookmark file is turned off.  You can always
+;;  use `M-~' to turn it back on again.  And remember that, as long as
+;;  you have not saved bookmarks after loading, you can always use
+;;  `C-u g' to revert to the bookmarks saved in the bookmark file.
+;;
+;;  To create additional bookmark files, to use either as alternatives
+;;  or as components, you can either copy an existing bookmark file or
+;;  use `bmkp-empty-file' (`C-x x 0') to create a new, empty bookmark
+;;  file.  If you use `C-x x 0' with an existing bookmark file, then
+;;  its bookmarks are all deleted - it is emptied.
+;;
+;;  Instead of simply copying a bookmark file, you can use
+;;  `bookmark-save' with a prefix argument, or use `bookmark-write'
+;;  (bound to `C-x x w'), to save the currently defined bookmarks to a
+;;  different bookmark file.
+;;
+;;  However a bookmark file was created, you can switch to it and then
+;;  add or delete bookmarks selectively, to change its content.
+;;  Remember too that you can delete bookmarks from the current set
+;;  using command `bookmark-delete' (`C-x x d') or, in the bookmark
+;;  list, using `d' plus `x' or marking then `D'.
+;;
+;;  Deleting bookmarks from a bookmark file is one way of editing it.
+;;  Another is to copy or move bookmarks from one bookmark file to
+;;  another.  In the bookmark-list display, you can copy or move the
+;;  marked bookmarks (or the current bookmark, if none are marked)
+;;  from the current bookmark file to another that you name, using `Y
+;;  > +' (`bmkp-bmenu-copy-marked-to-bookmark-file') and `Y > -'
+;;  (`bmkp-bmenu-move-marked-to-bookmark-file'), respectively.  And
+;;  you can use `Y > 0'
+;;  (`bmkp-bmenu-create-bookmark-file-from-marked') to create a new
+;;  bookmark file by copying the marked bookmarks.  With a prefix arg,
+;;  `Y > 0' creates also a bookmark-file bookmark.
+;;
+;;  In any location (any file or any buffer that can be bookmarked),
+;;  you can switch to a bookmark file that has only bookmarks for the
+;;  current file or buffer, creating such a file on the fly if none
+;;  exists.  To do this, use `C-x x C-l'
+;;  (`bmkp-switch-to-bookmark-file-this-file/buffer').
+;;
+;;  NOTE:
+;;
+;;    Unlike the other ways of organizing bookmarks into sets (tags,
+;;    bookmark-list bookmarks, etc.) bookmark files represent
+;;    physical, not logical, groupings of bookmarks.  A bookmark file
+;;    contains complete bookmark records.
+;;
+;;    If you copy a bookmark from one bookmark file to another, the
+;;    copy is an independent bookmark: it has no relation to the
+;;    bookmark it was copied from.  Changes to the copy or the
+;;    bookmark it was copied from do not affect each other.
+;;
+;;    This means that to use bookmark files for organizing bookmarks
+;;    you will typically move, not copy, bookmarks between them (or
+;;    copy and later delete).  Remember that you can load multiple
+;;    bookmark files to access their bookmarks together in a session.
+;;    Think of your bookmark files as independent modules that you can
+;;    combine.
+;;
+;;  See Also: (@> "Bookmark+ Load Order and Option `bookmark-default-file'").
+;;
+;;
+;;(@* "Bookmark-File Bookmarks")
+;;  *** Bookmark-File Bookmarks ***
+;;
+;;  A bookmark file is an excellent, persistent way to represent a set
+;;  of bookmarks.  In particular, it can represent a project or a
+;;  project component.  Switch among bookmark files to access
+;;  different projects.  Load project components as you need them.
+;;
+;;  You can load a bookmark file using `C-x x L' (switch) or `C-x x l'
+;;  (accumulate).  As a convenience, you can also load a bookmark file
+;;  by jumping to a bookmark-file bookmark.
+;;
+;;  You use command `bmkp-set-bookmark-file-bookmark', bound to `C-x x
+;;  y', to create a bookmark-file bookmark.  Jumping to such a
+;;  bookmark just loads the bookmark file that it records.  With `C-u'
+;;  (e.g. `C-u C-x j y project-foo'), jumping switches bookmark files.
+;;  Without `C-u' it accumulates the loaded bookmarks.
+;;
+;;  You can also use commands `bmkp-bookmark-file-load-jump' and
+;;  `bmkp-bookmark-file-switch-jump' (unbound by default), which load
+;;  and switch without prompting you for confirmation or whether to
+;;  first save the current bookmark file.
+;;
+;;  A bookmark-file bookmark is not only an added convenience.  You
+;;  can also use it in combination with other Bookmark+ features, such
+;;  as tagging.
+;;
+;;  As a shortcut, in Dired (if you use library `Dired+'), `C-M-b'
+;;  creates a bookmark-file bookmark.  The bookmark file that it
+;;  records contains autofile bookmarks to each of the files and
+;;  subdirectories that was marked in Dired at the time it was
+;;  created.  Jumping to that bookmark-file bookmark makes those
+;;  (marked) files and subdirectories available as bookmarks.  See
+;;  also (@> "Use Dired to Bookmark Files without Visiting Them").
+;;
+;;  Note that the bookmark file in which a bookmark-file bookmark is
+;;  recorded is not the same as the bookmark file recorded in that
+;;  bookmark.
+;;
+;;  For example, when you use `C-M-b' in Dired, the bookmark-file for
+;;  the marked files is, by default, file `.emacs.bmk' in the Dired
+;;  directory.  So if you are in directory `/foo/bar' the default
+;;  bookmark file for the marked files is `/foo/bar/.emacs.bmk'.  But
+;;  the new bookmark-file bookmark created is recorded in the current
+;;  bookmark file, whatever that might be (e.g. `~/.emacs.bmk').
+ 
+;;(@* "The Bookmark List Display")
+;;  ** The Bookmark List Display **
+;;
+;;  Bookmark+ enhances the bookmark list (aka the bookmark "menu
+;;  list", a misnomer) that is displayed in buffer `*Bookmark List*'
+;;  when you use `C-x x e' or `C-x r l' (command
+;;  `bookmark-bmenu-list').
+;;
+;;  At the top of the bookmark-list display is this header
+;;  information:
+;;
+;;  * The bookmark file used currently.  This is important because
+;;    Bookmark+ makes it easy for you to have multiple bookmark files
+;;    and switch among them.
+;;
+;;  * A title that describes the kinds of bookmarks listed, that is,
+;;    it reflects athe current filtering, if any.
+;;
+;;  For example, this header indicates that the current bookmark file
+;;  is `c:/.emacs.bmk' and only file and directory bookmarks are
+;;  shown:
+;;
+;;    Bookmark file:
+;;    c:/.emacs.bmk
+;;
+;;    File and Directory Bookmarks
+;;    ----------------------------
+;;
+;;  (Bookmark+ does not use the sliding header line of vanilla Emacs
+;;  24+, which means that option `bookmark-bmenu-use-header-line' has
+;;  no effect.  You do not need to see `Bookmark' and `File' column
+;;  headers as you scroll.)
+;;
+;;  Bookmarks are highlighted to indicate their type. You can mark and
+;;  unmark bookmarks, show or hide bookmarks of particular types, and
+;;  more.  Bookmarks that have tags are marked with a `t'.  Bookmarks
+;;  that have an annotation are marked with an `a' (not with a `*' as
+;;  in vanilla `bookmark.el').  Bookmarks that have been modified
+;;  since the last save of the bookmark file are marked with a `*'.
+;;  Bookmarks that have bookmark-highlight override settings (see
+;;  (@> "Defining How to Highlight")) are marked with a one-character
+;;  pink background.
+;;
+;;  Use `?' or `C-h m' in buffer `*Bookmark List*' for more
+;;  information about the bookmark list, including the following:
+;;
+;;  * The current status of sorting, filtering, and marking.
+;;
+;;  * A legend for the faces used for different bookmark types.
+;;
+;;
+;;(@* "Jumping To Bookmarks from the Bookmark List Display")
+;;  *** Jumping To Bookmarks from the Bookmark List Display ***
+;;
+;;  Bookmark visiting (jumping) commands are globally on prefix keys
+;;  `C-x j' and `C-x 4 j'.  In the bookmark-list display they are
+;;  additionally on `j' (other window) and `J' (same window).  In
+;;  addition, `j >' is bound to `bmkp-bmenu-jump-to-marked', which
+;;  jumps to each of the marked bookmarks in other windows.
+;;
+;;
+;;(@* "Tag Commands and Keys")
+;;  *** Tag Commands and Keys ***
+;;
+;;  There are lots of tag-related bookmark commands, and most are
+;;  bound to keys in buffer `*Bookmark List*' as well as to other keys
+;;  outside it.  How can you keep the commands straight or remember
+;;  their keys?
+;;
+;;  In the bookmark list display, tags-command keys begin with prefix
+;;  key `T'.  Elsewhere, they begin with prefix key `C-x x t' (or `C-x
+;;  j t', for jump commands - see (@> "Different Types of Jump Commands")).
+;;
+;;  `C-h m' (or `?') is your friend, of course.  Likewise `T C-h',
+;;  `C-x x t C-h', and `C-h >' (which describes the marked bookmarks).
+;;  Beyond that, the tag-related keys that are more than two
+;;  keystrokes are organized as follows:
+;;
+;;    They all have the prefix key `T'.
+;;
+;;    `m' means mark
+;;    `u' means unmark
+;;    `>' stands for the marked bookmarks
+;;    `*' means AND (set intersection; all)
+;;    `+' means OR  (set union; some/any)
+;;    `~' means NOT (set complement)
+;;
+;;  The key `T m *', for instance, marks (`m') the bookmarks that are
+;;  tagged with all (`*' = AND) of a given set of tags.  It prompts you
+;;  for one or more tags that the bookmarks must have, and it marks
+;;  all bookmarks that have all of the tags you enter.
+;;
+;;  The key `T u ~ +' unmarks (`u') the bookmarks that do not (`~')
+;;  have any (`+' = OR) of the tags you specify.  And so on.
+;;
+;;  The marking and unmarking commands for tags compare the tags a
+;;  bookmark has with tags that you enter.  Any bookmarks that have no
+;;  tags are ignored - they are neither marked nor unmarked by these
+;;  commands.
+;;
+;;  `+' and `-' can also mean add and remove tags, respectively, and
+;;  `>' stands for the marked bookmarks.  So `T > +' adds (`+') one or
+;;  more tags to each of the marked (`>') bookmarks.
+;;
+;;  In general, the tag-related commands let you enter a set of tags,
+;;  one at a time.  Thus, instead of having a command that adds a
+;;  single tag to the current bookmark, you have a command that adds
+;;  any number of tags to it.  To add just a single tag, hit `RET'
+;;  twice: once to enter the tag, and once again to indicate that it
+;;  is the last (i.e., the only) one.
+;;
+;;  If you just hit `RET' immediately, specifying an empty set of
+;;  tags, then each of the commands does something appropriate.  For
+;;  `T m *', for instance, an empty list of tags means to mark (only)
+;;  the bookmarks that have any tags at all.
+;;
+;;  Finally, for the marking/unmarking tags commands, a prefix
+;;  argument flips the sense of the command, in this way:
+;;
+;;  "some are" -> "some are NOT", i.e., "not all are" (and vice versa)
+;;  "all are"  -> "all are NOT",  i.e., "none are"    (and vice versa)
+;;
+;;  In other words:
+;;
+;;    C-u T m *    =  T m ~ +  (all are NOT      = not some are)
+;;    C-u T m ~ +  =  T m *    (not some are NOT = all are)
+;;    C-u T m +    =  T m ~ *  (some are NOT     = not all are)
+;;    C-u T m ~ *  =  T m +    (not all are NOT  = some are)
+;;
+;;  You'll figure it out ;-).
+;;
+;;  Other important keys pertaining to tags (the keys in parentheses
+;;  work in any buffer, not just buffer `*Bookmark List*'):
+;;
+;;  * `C-h RET' (`C-h M') shows you the tags that belong to a
+;;    bookmark.  With a prefix argument it shows you the full internal
+;;    form of the tags, that is, the name+value pairs.
+;;
+;;  * `C-h >' describes all of the marked bookmarks, in the current
+;;    sort order.  The descriptions include the tags.  (You can use `T
+;;    m * RET' to mark all of the tagged bookmarks.)
+;;
+;;  * `T e' (`C-x x t e') lets you edit a bookmark's tags.
+;;
+;;  * `T l' (`C-x x t l') lists all tags currently known to Emacs
+;;     (across all bookmarks).
+;;
+;;  * `T +' (`C-x x t + b') adds some tags to a bookmark.
+;;    `T -' (`C-x x t - b') removes some tags from a bookmark.
+;;    `T 0' (`C-x x t 0) removes all tags from a bookmark.
+;;    `T d' (`C-x x t d) removes a set of tags from all bookmarks.
+;;
+;;  In the bookmark list display you can also sort bookmarks according
+;;  to how they are tagged, even in complex ways.  See
+;;  (@> "Sorting Bookmarks").
+;;
+;;
+;;(@* "Tags: Sets of Bookmarks")
+;;  *** Tags: Sets of Bookmarks ***
+;;
+;;  The best way to think about tags is as names of sets.  All
+;;  bookmarks tagged `blue' constitute the bookmark set named `blue'.
+;;
+;;  The bookmarks visible in the bookmark list at any time also
+;;  constitute an unnamed set.  Likewise, the marked bookmarks and the
+;;  unmarked bookmarks are unnamed sets.  Bookmark+ is all about
+;;  helping you act on sets of Emacs objects.  Bookmarks are named,
+;;  persistent pointers to objects such as files and filesets.
+;;  Bookmark tags are named, persistent sets of bookmarks (and hence
+;;  of their target objects).
+;;
+;;  The marking commands make it easy to combine sets as unions or
+;;  intersections.  And you can give the result a name for quick
+;;  access later, just by adding a new tag.  in other words, do the
+;;  set-definition work only once, and name the result.
+;;
+;;  How would you tag as `Java IDE Projects' the bookmarks that are
+;;  already tagged both `Java' and `ide'?
+;;
+;;  1. `T m * Java RET ide RET RET', to mark them.
+;;  2. `T > + Java IDE Projects RET RET, to tag them.
+;;
+;;  How would you sort your bookmarks, to show all those tagged both
+;;  `blue' and `moon' first?
+;;
+;;  1. `T m * blue RET moon RET RET', to mark them.
+;;  2. `s >' to sort the marked bookmarks first
+;;     (see (@> "Sorting Bookmarks"), below).
+;;
+;;  If you wanted to show only the marked bookmarks, instead of
+;;  sorting to put them first in the list, you would use `>'
+;;  instead of `s >'.
+;;
+;;  How would you query-replace the set of files that are tagged with
+;;  any of the tags `alpha', `beta', and `gamma', but are not tagged
+;;  `blue' or `moon'?
+;;
+;;    1. `F S', to show only the file bookmarks.
+;;    2. `T m + alpha RET beta RET gamma RET RET', to mark the
+;;       bookmarks that have at least one of those tags.
+;;    3. `T u + blue RET moon RET RET', to unmark those that are
+;;       tagged `blue' or `moon'.
+;;    4. `M-q' to query-replace the marked files.
+;;
+;;  If that were a set of files that you used often, then you would
+;;  name the set by giving the files a new tag.
+;;
+;;  The point is that bookmarks, and bookmark tags in particular, let
+;;  you define and manipulate sets of Emacs objects.  It doesn't
+;;  matter how you define such a set: regexp matching (marking,
+;;  filtering), by object type, by tag combinations...  Sets need not
+;;  be named to act on them, but you can provide them with persistent
+;;  names (tags) to avoid redefining them over and over.  Manipulation
+;;  of bookmarked objects includes visiting, searching, and
+;;  query-replacing.  And you can define your own bookmark types
+;;  (using bookmark handlers) and associated manipulations.
+;;
+;;
+;;(@* "Open Dired for the Marked File Bookmarks")
+;;  *** Open Dired for the Marked File Bookmarks ***
+;;
+;;  You've seen that the bookmark list has many features that are
+;;  similar to Dired features.  But Dired is specialized for files and
+;;  directories, and it has many more features for manipulating them.
+;;  The bookmark list is not intended to replace Dired.
+;;
+;;  You can, however, use the bookmark list to take advantage of
+;;  arbitrary Dired features for file and directory bookmarks.
+;;  Command `bmkp-bmenu-dired-marked' (`M-d >') weds Bookmark+'s
+;;  set-defining and set-manipulating features (tagging, marking,
+;;  filtering etc.) to Dired's file-manipulating features.
+;;
+;;  `M-d >' opens a Dired buffer that is specialized for just the
+;;  files and directories whose bookmarks are marked in the bookmark
+;;  list.  (Other marked bookmarks are ignored by the command.)  The
+;;  files and directories can be located anywhere; they need not be in
+;;  the same directory.  They are listed in Dired using absolute file
+;;  names.
+;;
+;;  (In Emacs versions prior to release 23.2, only local files and
+;;  directories can be handled, due to Emacs bug #5478.  In such
+;;  versions, remote-file bookmarks are ignored by `M-d >'.)
+;;
+;;  This Bookmark+ feature makes sets of files and directories
+;;  immediately amenable to all of the operations provided by Dired.
+;;
+;;  It is particularly useful in conjunction with tags.  Use bookmark
+;;  tags and marks to define a possibly complex set of file and
+;;  directory bookmarks.  Then hit `M-d >' to list them in a Dired
+;;  buffer.  Then use any Dired commands you want to act on any of
+;;  them.
+;;
+;;  For example, to compress bookmarked files that are tagged with
+;;  both `blue' and `moon':
+;;
+;;  1. Mark them using `T m * blue RET moon RET RET'.
+;;  2. Open Dired for them using `M-d >'.
+;;  3. Mark them in Dired, then compress them using `Z'.
+;;
+;;  Since tags are persistent, Bookmark+ gives you a good way to
+;;  define an arbitrary set of files as a project and then open them
+;;  in Dired at any time to operate on them.
+;;
+;;  If you use `Dired+' (library `dired+.el'), then a similar feature
+;;  is available for the marked files and directories: You can use
+;;  `C-M-*' in Dired to open a separate Dired buffer for them only.
+;;  You can of course then bookmark that resulting Dired buffer, if
+;;  you like.
+;;
+;;  If you use `Icicles', then whenever you use a command that reads a
+;;  file (or directory) name, you can use `M-|' during file-name
+;;  completion to open Dired on the currently matching set of file
+;;  names.  That is, this is the same kind of special Dired buffer
+;;  that is provided for file and directory bookmarks by `M-d >' in
+;;  the bookmark list.
+;;
+;;
+;;(@* "Marking and Unmarking Bookmarks")
+;;  *** Marking and Unmarking Bookmarks ***
+;;
+;;  Bookmark+ enhances the marking and unmarking of bookmarks in the
+;;  bookmark list in several ways.  These enhancements are similar to
+;;  features offered by Dired and Dired-X.  You can use:
+;;
+;;  * `% m' to mark the bookmarks that match a regexp.  The entire
+;;    line in the bookmark list is checked for a match, that is, both
+;;    the bookmark name and the file name, if shown.
+;;
+;;  * `M-DEL' (or `U') to unmark all bookmarks, or all that are marked
+;;    `>', or all that are flagged `D' for deletion.
+;;
+;;  * `t' to toggle (swap) the marked and unmarked bookmarks: those
+;;    that are marked become unmarked, and vice versa.
+;;
+;;  * `>' to show only the marked bookmarks or `<' to show only the
+;;    unmarked bookmarks.  Repeat to show them all again.
+;;
+;;  * `F M', `I M' etc. to mark only the file bookmarks, Info
+;;    bookmarks etc.  (The first key here is the same as the
+;;    corresponding filter key, e.g. `F' for files - see next topic.)
+;;
+;;  * `O M' to mark the orphaned bookmarks, that is, those whose
+;;    recorded files have been renamed or deleted.  You can then
+;;    relocate or delete the bookmarks, as appropriate.
+;;
+;;
+;;(@* "Filtering Bookmarks (Hiding and Showing)")
+;;  *** Filtering Bookmarks (Hiding and Showing) ***
+;;
+;;  There are three ways to show only certain bookmarks.
+;;
+;;  1. Filter by bookmark type.
+;;
+;;  2. Filter bookmarks incrementally and temporarily, using pattern
+;;     matching.
+;;
+;;  3. Filter out the marked or unmarked bookmarks.
+;;
+;;  * Filtering by bookmark type
+;;
+;;    The commands that show only bookmarks of a particular type are
+;;    bound to keys that end in `S' (for "show").  For example, `I S'
+;;    shows only Info bookmarks, and `X S' shows only temporary
+;;    bookmarks.
+;;
+;;    The type filter is reflected in the bookmark-list display title.
+;;    It says `All Bookmarks' if no type filter is used.  Otherwise it
+;;    tells you what kind of bookmarks are listed: `Autonamed
+;;    Bookmarks', `File and Directory Bookmarks', and so on.
+;;
+;;    Note: It is only filtering by bookmark type that is remembered
+;;    when you save a bookmark-list display state or you create a
+;;    bookmark-list bookmark.  See (@> "State-Restoring Commands and Bookmarks").
+;;
+;;  * Filtering incrementally by pattern matching
+;;
+;;    These commands show only bookmarks that in some way match a
+;;    pattern (regexp) that you type.  The bookmarks are filtered
+;;    incrementally as you type the pattern.  Hit any non-inserting
+;;    key, such as `RET', to finish defining the pattern.
+;;
+;;    The commands for this are bound to keys that start with `P' (for
+;;    "pattern").  For example, `P B' shows only bookmarks whose names
+;;    match the regexp, `P F' shows those whose file names match, `P
+;;    A' shows those whose annotations match, and `P T' shows those
+;;    that have one or more tags that match.  (See (@> "Bookmark Tags"),
+;;    above, for information about tags.)
+;;
+;;  * Filtering based on marking
+;;
+;;    Just as in Dired, you can use `% m' to mark the bookmarks that
+;;    match a regexp.  Then use `>' to show only the marked bookmarks.
+;;    See (@> "Marking and Unmarking Bookmarks"), above.
+;;
+;;    This method has the advantage that you can show the complement,
+;;    the bookmarks that do *not* match the regexp, by using `<'
+;;    instead of `>'.  It also has the advantage that matching checks
+;;    the combination of bookmark name and file name (use `M-t' to
+;;    toggle showing file names).
+;;
+;;
+;;(@* "Only Visible Bookmarks Are Affected")
+;;  *** Only Visible Bookmarks Are Affected ***
+;;
+;;  Commands that operate on the current bookmark or on the marked or
+;;  the unmarked bookmarks act only on bookmarks that are displayed
+;;  (not hidden).  This includes the commands that mark or unmark
+;;  bookmarks.  This means that you can easily define any given set of
+;;  bookmarks.
+;;
+;;  For example:
+;;
+;;    Use `F S' to show only bookmarks associated with files.
+;;    Use `% m' to mark those that match a particular regexp.
+;;    Use `R S' to show only bookmarks that have regions.
+;;    Use `m' to mark some of those region bookmarks individually.
+;;    Use `.' to show all bookmarks.
+;;    Use `t' to swap marked and unmarked (so unmarked are now marked)
+;;    Use `D' to delete all of the marked bookmarks (after confirming)
+;;
+;;  Together, steps 1-7 delete all file bookmarks that match the
+;;  regexp and all region bookmarks that you selectively marked.
+;;
+;;
+;;(@* "Omitting Bookmarks from Display")
+;;  *** Omitting Bookmarks from Display ***
+;;
+;;  In sections (@> "Marking and Unmarking Bookmarks") and
+;;  (@> "Filtering Bookmarks (Hiding and Showing)") you learned how
+;;  to hide and show bookmarks in the bookmark list.  This section is
+;;  about a different kind of hiding, called "omitting".
+;;
+;;  Omitted bookmarks are not shown in the bookmark list, no matter
+;;  what filtering is used.  The only way to show omitted bookmarks is
+;;  to show all of them and only them, using `- S', which is bound to
+;;  command `bmkp-bmenu-show-only-omitted'.
+;;
+;;  Omitted bookmarks are still available even if they are not shown,
+;;  and you can still jump to them (e.g. using `C-x r b').  You just
+;;  don't see them in the bookmark list.  And that's the reason for
+;;  this feature: to hide those bookmarks that you don't care to see.
+;;
+;;  One use for this feature is to hide the component bookmarks that
+;;  make up a sequence bookmark (see
+;;  (@> "Function, Sequence, Variable-List,... Bookmarks")).  The
+;;  default behavior when you create a sequence bookmark is in fact to
+;;  omit its component bookmarks from the displayed list.
+;;
+;;  You can omit any bookmarks by marking them and then using `- >'
+;;  (`bmkp-bmenu-omit/unomit-marked').  If you are looking at the
+;;  omitted bookmarks (after using `- S'), then `- >' un-omits the
+;;  bookmarks marked there.  Think of two complementary spaces: the
+;;  normal bookmark list and the omitted bookmark list.  When you use
+;;  `- >', the marked bookmarks that are currently shown are moved to
+;;  the opposite space.
+;;
+;;  You can un-omit all of the omitted bookmarks at once, using `- U'
+;;  (`bmkp-unomit-all').  You can also call this command from outside
+;;  the bookmark-list display.
+;;
+;;  Omitted bookmarks that are marked are generally not included when
+;;  you use a command that acts on the marked bookmarks.  However, if
+;;  you use a negative prefix argument with the command then they are.
+;;
+;;  For some commands this is relaxed so that any prefix arg has this
+;;  effect.  For other commands a non-negative prefix arg has a
+;;  different effect.  In some cases, a non-negative prefix arg has
+;;  one effect and a non-positive prefix arg has the effect of
+;;  including omitted marked bookmarks, so that a zero prefix arg has
+;;  both effects.  For any given command, consult the doc string for
+;;  full information.
+;;
+;;
+;;(@* "Sorting Bookmarks")
+;;  *** Sorting Bookmarks ***
+;;
+;;  Filtering hides certain kinds of bookmarks.  Sometimes, you want
+;;  to see bookmarks of various kinds, but you want them to be grouped
+;;  or sorted in different ways, for easy recognition, comparison, and
+;;  access.
+;;
+;;  Bookmarks shown in the bookmark list are sorted using the current
+;;  value of option `bmkp-sort-comparer'.  (If that is `nil', they are
+;;  unsorted, which means they appear in reverse chronological order
+;;  of their creation.)
+;;
+;;  You can use `s s'... (repeat hitting the `s' key) to cycle among
+;;  the various sort orders possible, updating the display
+;;  accordingly.  By default, you cycle among all available sort
+;;  orders, but you can shorten the cycling list by customizing option
+;;  `bmkp-sort-orders-for-cycling-alist'.
+;;
+;;  You can also change directly to one of the main sort orders
+;;  (without cycling) using `s >', `s n', `s f n', etc.  There are
+;;  many such predefined sort orders bound to keys with the prefix `s'
+;;  - use `C-h m' or `?'  for more info.
+;;
+;;  `s >'   â€“ Sort marked (`>') before unmarked
+;;  `s *'   â€“ Sort modified (`*') before unmodified
+;;  `s 0'   â€“ Sort by bookmark creation date/time
+;;  `s b'   â€“ Sort by last buffer or file access
+;;  `s a'   â€“ Sort annotated (`a') before unannotated
+;;  `s d'   â€“ Sort by last bookmark access date/time
+;;  `s D'   â€“ Sort flagged (`D') before unflagged
+;;  `s f d' â€“ Sort by last local file access date/time
+;;  `s f k' â€“ Sort by local file kind: file, symlink, dir
+;;  `s f n' â€“ Sort by file name
+;;  `s f s' â€“ Sort by local file size
+;;  `s f u' â€“ Sort by last local file update (edit) date/time
+;;  `s g'   â€“ Sort by Gnus thread: group, article, message.
+;;  `s i'   â€“ Sort by Info manual, node, position
+;;  `s k'   â€“ Sort by bookmark type (kind)
+;;  `s n'   â€“ Sort by bookmark name
+;;  `s t'   â€“ Sort tagged (`t') before untagged
+;;  `s v'   â€“ Sort by visit frequency
+;;
+;;  You can reverse the current sort direction (ascending/descending)
+;;  using `s r'.  Also, repeating any of the main sort-order commands
+;;  (e.g. `s n') cycles among that order, the reverse, and unsorted.
+;;
+;;  For a complex sort, which involves composing several sorting
+;;  conditions, you can also use `s C-r' to reverse the order of
+;;  bookmark sorting groups or the order within each group (depending
+;;  on whether `s r' is also used).  Try it, for example, together
+;;  with sorting by bookmark kind (`s k').
+;;
+;;  Be aware that `s C-r' can be a bit unintuitive.  If it does not do
+;;  what you expect or want, or if it confuses you, then don't use it
+;;  ;-).  (`s C-r' has no noticeable effect on simple sorting.)
+;;
+;;  Remember that you can combine sorting with filtering different
+;;  sets of bookmarks - bookmarks of different kinds (e.g. Info) or
+;;  bookmarks that are marked or unmarked.
+;;
+;;  Finally, you can easily define your own sorting commands and sort
+;;  orders.  See macro `bmkp-define-sort-command' and the
+;;  documentation for option `bmkp-sort-comparer'.  (Bookmark+ uses
+;;  option `bmkp-sort-comparer'; it *ignores* vanilla Emacs option
+;;  `bookmark-sort-flag'.)
+;;
+;;  Of particular note is that you can interactively define commands
+;;  that sort by a given list of tags - you use keys `T s' (command
+;;  `bmkp-define-tags-sort-command') to do that.  You are prompted for
+;;  the tags to sort by.  Bookmarks are sorted first according to
+;;  whether they are tagged with the first tag, then the second tag,
+;;  and so on.  Otherwise, sorting is by bookmark name.
+;;
+;;  The tags you specify are used, in order, in the name of the new
+;;  command.  For example, if you enter tags `alpha', `beta', and
+;;  `gamma', in that order, then the sorting command created is
+;;  `bmkp-bmenu-sort-alpha-beta-gamma'.  The new command is saved in
+;;  your bookmark commands file (`bmkp-bmenu-commands-file').
+;;
+;;  Note that because you can add a new tag to all bookmarks that have
+;;  some given set of tags, you can use that single (new) tag to
+;;  represent the entire tag set.  Sorting by that tag is then the
+;;  same as sorting by the tag set.  You can of course use overlapping
+;;  sets in the composite sort command.  You can, for example, sort
+;;  first according to tag `tag1', which represents the set of tags
+;;  `alpha', `beta', `gamma', `delta', and then sort according to tag
+;;  `tag2', which represents the set of tags `beta', `delta'.
+;;
+;;  See also (@> "Use Bookmark+ with Icicles") - the same technique is
+;;  used in `Icicles' for sorting bookmarks as completion candidates.
+ 
+;;(@* "Bookmarks for Specific Files or Buffers")
+;;  ** Bookmarks for Specific Files or Buffers **
+;;
+;;  A bookmark typically records a position or a region in a file or
+;;  buffer.  Sometimes you are interested in accessing or examining
+;;  only the bookmarks for particular files or buffers.  For example,
+;;  you might want to navigate among the bookmarks for the current
+;;  buffer.  Or you might want to search the regions recorded in the
+;;  bookmarks for a particular file.
+;;
+;;  For a bookmark, the recorded file and buffer name differ in that
+;;  the file name is absolute.  Bookmarks for buffer `foo.el' include
+;;  all files named `foo.el', whereas bookmarks for file
+;;  `/project1/lisp/foo.el' include only the files in that one
+;;  directory.
+;;
+;;  Another important difference is that when multiple buffers visit
+;;  different files that have the same relative file name (i.e., in
+;;  different directories), Emacs makes the buffer names unique by
+;;  appending `<N>' as needed, where `N' is 2, 3,...  When you create
+;;  a bookmark, the current buffer name is recorded as the bookmark's
+;;  buffer.  If the current buffer is not visiting a file, then the
+;;  bookmark created is a non-file bookmark.  In that case, to use the
+;;  bookmark later you must have a buffer of the same name
+;;  (e.g. `foo.el<2>').
+;;
+;;  Bookmark+ provides commands to handle these different use cases:
+;;  specific files and specific buffers.  The keys bound to these
+;;  commands use `f' for file and `b' for buffer.  In the
+;;  bookmark-list display, the following keys affect the bookmarks for
+;;  a particular file or buffer whose name you provide (with
+;;  completion).
+;;
+;;  * `= f M' and `= b M' - mark 
+;;  * `= f S' and `= b S' - show (only)
+;;
+;;  For navigation, the following keys jump to bookmarks for
+;;  particular files or buffers.  (Use `C-x 4 j' for other-window.)
+;;
+;;  * `C-x j ,,'                  - current buffer
+;;  * `C-x j = f' and `C-x j = b' - specified file(s) or buffer(s)
+;;
+;;  For the `=' keys you are prompted for one or more file names or
+;;  buffer names.
+;;
+;;  Finally, because the bookmarks in the current buffer can be of
+;;  particular interest, `C-x x ,' opens the bookmark-list display for
+;;  only those bookmarks.  (`,' stands generally for "this-buffer" in
+;;  Bookmark+ key bindings.)
+ 
+;;(@* "Cycling, Navigation List")
+;;  ** "Cycling, Navigation List" **
+;;
+;;  Using completion to jump to a bookmark is handy.  It lets you
+;;  choose a bookmark by its name and gives you direct ("random")
+;;  access to it.
+;;
+;;  Sometimes, however, you don't much care what a bookmark is named,
+;;  and you want to cycle quickly among relatively few, related
+;;  bookmarks.  Obviously, the smaller the number of bookmarks in the
+;;  set, the more convenient cycling is - with many bookmarks cycling
+;;  can become tedious.
+;;
+;;  An analogy: If your TV has lots of channels, then the channel
+;;  up/down buttons on the remote control are not so useful: 32, 33,
+;;  34, ..., 79!  Unless the channel you want happens to be near the
+;;  current channel, cycling around a huge ring of channels is not the
+;;  way to go.  And just because your TV receives lots of channels
+;;  does not mean that you watch them all or that you are equally
+;;  interested in them all.
+;;
+;;  Some TV remote controls have a feature that mitigates this
+;;  problem.  You can define a ring of favorite channels, and there
+;;  are two additional buttons that let you cycle forward and backward
+;;  around the ring, skipping the channels in between.  The number of
+;;  favorites is relatively small, so cycling is not tedious.  More
+;;  importantly, all of the channels in the ring are ones you are
+;;  interested in.
+;;
+;;  Extend this idea to allow for assigning different sets of channels
+;;  to the favorites ring at different times: choose the ring you want
+;;  at any time: sports, music, films, science, art, history, and so
+;;  on.  Add the possibility of sorting those sets in various ways, to
+;;  further facilitate cycling, and you arrive at the idea behind the
+;;  Bookmark+ navigation list.
+;;
+;;  Another analogy is a music playlist.  You can use Bookmark+ as a
+;;  simple music player by bookmarking music files.  Similarly, you
+;;  can use Bookmark+ to create slideshows by bookmarking image files.
+;;  Cycle the navigation list to move through the slide show.
+;;
+;;  If you use MS Windows, you can take advantage of your existing
+;;  file associations to open your bookmarks using the appropriate
+;;  program - no need to define a new bookmark type and handler.  See
+;;  (@> "Bookmarking Files That You Cannot Visit with Emacs").
+;;
+;;  Note: The default value of option `bmkp-use-region' is `t', not
+;;  `cycling-too', which means that when you cycle to a bookmark its
+;;  recorded region (if any) is not activated.  This is probably what
+;;  you want most of the time.  Cycling is a repetitive action, and if
+;;  you cycle to a bookmark with no recorded region then an already
+;;  active region is just extended.  Customize the value to
+;;  `cycling-too' if you prefer that behavior.
+;;
+;;
+;;(@* "The Bookmark Navigation List")
+;; *** "The Bookmark Navigation List ***
+;;
+;;  Bookmark+ is all about letting you define and manipulate sets of
+;;  bookmarks.  When a bookmark set can be used for cycling (as well
+;;  as jumping) it is called the "navigation list" or "navlist", for
+;;  short.
+;;
+;;  In other words, Bookmark+ lets you cycle among any set of
+;;  bookmarks.  When you cycle, it is the set that currently
+;;  constitutes the navigation list that is cycled.
+;;
+;;  Here are two ways to define the navigation list:
+;;
+;;  * `C-x x :' (`bmkp-choose-navlist-of-type') - As the set of all
+;;    bookmarks of a certain type (`any' or empty input means use all
+;;    bookmarks).
+;;
+;;  * `C-x x B' (`bmkp-choose-navlist-from-bookmark-list') - As the
+;;    set of all bookmarks corresponding to a bookmark-list bookmark,
+;;    that is the bookmarks corresponding to a given recorded state of
+;;    buffer `*Bookmark List*'.
+;;
+;;  Each of these lets you choose a set of bookmarks using completion.
+;;  For `C-x x :' you are prompted for the type of bookmark
+;;  (e.g. `dired').
+;;
+;;  For `C-x x B' you are prompted for the name of a bookmark-list
+;;  bookmark that you created.  But you can also choose the candidate
+;;  `CURRENT *Bookmark List*' to capture the bookmarks that would be
+;;  shown currently in the `*Bookmark List*' (even if the list is not
+;;  displayed now).  See (@> "State-Restoring Commands and Bookmarks")
+;;  for information about bookmark-list bookmarks.
+;;
+;;  If you do not define the navigation list before you start cycling,
+;;  it is automatically defined as follows:
+;;
+;;  * If you cycle using a current-file/buffer cycling key such as
+;;    `C-x x down' (see (@> "Cycling in the Current File/Buffer"))
+;;    then the bookmarks in the current file or buffer are used as the
+;;    navlist.
+;;
+;;  * Otherwise, a snapshot is taken of the the bookmarks currently in
+;;    the global bookmark list (the value of variable
+;;    `bookmark-alist') as the navlist.
+;;
+;;  However the navlist is defined, it is important to remember this:
+;;  it is a static snapshot of some set of bookmarks taken at a given
+;;  time.  Subsequent changes to the bookmark list that was copied are
+;;  not reflected in the navlist.  If you add a bookmark it will not
+;;  be among those cycled.  But see also
+;;  (@> "Cycling Dynamic Sets of Bookmarks") for how to cycle dynamic
+;;  sets.
+;;
+;;  You can update the navlist at any time by taking another snapshot
+;;  of the same bookmark list you used for the last snapshot.  For the
+;;  global bookmark list just use `C-x x : RET'.  (You can of course
+;;  bind that action to a shorter key sequence if you like.)
+;;
+;;  Besides cycling among the bookmarks of the navlist (see next),
+;;  once you have defined the navigation list you can use `C-x j N' or
+;;  `C-x 4 j N' to jump to its bookmarks, as mentioned in section
+;;  (@> "Different Types of Jump Commands").
+;;
+;;  Note that just because you might have used `C-x x B' to define the
+;;  navlist using a particular bookmark-list bookmark or the current
+;;  `*Bookmark List*' state, that does not mean that the `*Bookmark
+;;  List*' state at any given time necessarily reflects the navlist
+;;  bookmarks.  The two are separate.  You can, however, open the
+;;  `*Bookmark List*' so that it reflects the bookmarks currently in
+;;  the navigation list, using `C-x x N' (`bmkp-navlist-bmenu-list').
+;;  
+;;
+;;(@* "Cycling the Navigation List")
+;; *** "Cycling the Navigation List" ***
+;;
+;;  So you choose a navigation list.  How do you then cycle among its
+;;  bookmarks?
+;;
+;;  Commands `bmkp-next-bookmark' and `bmkp-previous-bookmark' cycle
+;;  to the next and previous bookmark in the navigation list (with
+;;  wraparound).  (There are also other-window versions of these
+;;  commands.)
+;;
+;;  You can bind these to any keys you like, but it's obviously better
+;;  to choose keys that are easily repeatable (e.g. by holding them
+;;  pressed).  Some people who are used to using MS Visual Studio
+;;  might want to use `f2' and `S-f2' to cycle forward and backward.
+;;
+;;  Bookmark+ does not define such key bindings, but you can.  What it
+;;  does is define repeatable keys on the `bookmark-map' keymap, which
+;;  by default has prefix `C-x x'.  To do this it binds similar
+;;  commands that can be repeated by simply repeating the key-sequence
+;;  suffix.  These are the (default) keys:
+;;
+;;  Forward:  `C-x x f', `C-x x C-f', `C-x x right'
+;;  Backward: `C-x x b', `C-x x C-b', `C-x x left'
+;;
+;;  (If you use an Emacs version prior to Emacs 22, you cannot use
+;;  this prefix-key repeatable feature.)
+;;
+;;  In addition, if you use MS Windows then you can invoke the Windows
+;;  `Open' action on each bookmark when you cycle, to act on its file
+;;  using the program associated with the file type.  This lets you
+;;  play music or display images in a playlist or slideshow fashion.
+;;  These are the keys to do that:
+;;
+;;  Forward:  `C-x x next'   (PageDown key)
+;;  Backward: `C-x x prior'  (PageUp key)
+;;
+;;  Being able to cycle among an arbitrary set of bookmarks is the
+;;  most important feature of Bookmark+ cycling.  The other important
+;;  feature is that if the navigation list is defined by `*Bookmark
+;;  List*' then the characteristics of that bookmark display are
+;;  respected for navigation.  Only the bookmarks visible in
+;;  `*Bookmark List*' are included, and the `*Bookmark List*' sort
+;;  order is used for navigation.
+;;
+;;  So you can not only choose any set of bookmarks for cycling at any
+;;  given time, you can also cycle among them in an order you choose.
+;;  For example, if in the bookmark list display (`C-x x e' or `C-x r
+;;  l') you show only those file bookmarks that belong to a given
+;;  project, and you have them sorted by file size, then cycling moves
+;;  among only those files, in file-size order.
+;;
+;;  This is a main reason you will want to define bookmark-list
+;;  bookmarks, which record a specific set of bookmarks and their sort
+;;  order: to later choose given sets in different contexts for
+;;  cycling.
+;;
+;;
+;;(@* "Cycling Dynamic Sets of Bookmarks")
+;; *** "Cycling Dynamic Sets of Bookmarks" ***
+;;
+;;  The fact that the navlist is a static snapshot is a useful
+;;  feature, but sometimes you might want to cycle among a particular
+;;  dynamic set of bookmarks, that is, to have cycling take changes to
+;;  the bookmark set into account automatically.  For that, Bookmark+
+;;  provides separate cycling commands for most types of bookmark.
+;;
+;;  By default, these different kinds of cycling commands are not
+;;  bound to any keys, with the exception of the commands for cycling
+;;  the current fle or buffer.  This exception includes cycling all
+;;  bookmarks for the current file/buffer
+;;  (see (@> "Cycling in the Current File/Buffer")
+;;  and cycling only the highlighted bookmarks for the current
+;;  file/buffer (see (@> "Using Highlighted Bookmarks")).  Keys `C-x x
+;;  down' and `C-x x C-down' are defined for these two kinds of
+;;  current-buffer cycling.
+;;
+;;  If you often want to cycle among the bookmarks of some other
+;;  particular kind (e.g. only the autonamed bookmarks), then you can
+;;  bind the relevant commands
+;;  (e.g. `bmkp-next-autonamed-bookmark-repeat',
+;;  `bmkp-previous-autonamed-bookmark-repeat', or their other-window
+;;  versions) to handy keys.  Otherwise, you can just use the cycling
+;;  commands without binding them.
+;;
+;;
+;;(@* "Cycling in the Current File/Buffer")
+;; *** "Cycling in the Current File/Buffer" ***
+;;
+;;  You can navigate the bookmarks in the current file or buffer by
+;;  cycling as well as jumping.  It is convenient to have dedicated
+;;  keys for this, separate from the keys to cycle the navigation
+;;  list.  The following keys are defined, corresponding to commands
+;;  `bmkp-next-bookmark-this-file/buffer-repeat' and
+;;  `bmkp-previous-bookmark-this-file/buffer-repeat':
+;;
+;;  Next:     `C-x x n', `C-x x C-n', `C-x x down'
+;;  Previous: `C-x x p', `C-x x C-p', `C-x x up'
+;;
+;;  Starting with Emacs 23.3 (Emacs fix for bug #6256), you can also
+;;  use the mouse wheel to cycle: `C-x x' then just rotate the wheel.
+;;
+;;  Again, you can bind any keys you want to these commands
+;;  (e.g. `f2', `S-f2').  If you do not need to use a prefix key, then
+;;  bind commands `bmkp-next-bookmark-this-file/buffer' and
+;;  `bmkp-previous-bookmark-this-file/buffer' (no -repeat).
+;;
+;;  You can also cycle among just the highlighted bookmarks in the
+;;  current file or buffer - see (@> "Using Highlighted Bookmarks").
+;;
+;;  Cycling among bookmarks for the current file or buffer (whether
+;;  all or only the highlighted ones) is dynamic: the current set of
+;;  bookmarks is cycled, not a static snapshot taken at some point in
+;;  past.  The navlist is automatically updated to the current dynamic
+;;  set each time you cycle.  This is different from the usual cycling
+;;  of the navlist, where it is taken as a static snapshot -
+;;  see (@> "The Bookmark Navigation List").
+;;
+;;  By default, you cycle among the bookmarks for the current file or
+;;  buffer in order of their buffer positions, top to bottom.  If you
+;;  want a different order, you can customize option
+;;  `bmkp-this-file/buffer-cycle-sort-comparer'.
+;;
+;;  Alternatively, you can use `C-x x ,' to display the `*Bookmark
+;;  List*' with only the current file/buffer's bookmarks, sort them
+;;  there, and then use `C-x x B' to set the navigation list to
+;;  `CURRENT *Bookmark List*'.  In that case, you use the navlist
+;;  cycling keys (e.g. `C-x x f', not `C-x x n'), and the cycled set
+;;  is a static snapshot.
+;;
+;;  Note that the keys mentioned here cycle bookmarks for the current
+;;  file if visiting a file, or the current buffer otherwise.  There
+;;  are also commands (unbound to keys) for cycling bookmarks for the
+;;  current file only or the current buffer only.
+;;
+;;  The bookmarks for the current buffer are those that were created
+;;  in a buffer of exactly the same name.  If one buffer visits a file
+;;  `foo.el', and another buffer visits a different file of the same
+;;  name (i.e., in a different directory), the second buffer will have
+;;  the name `foo.el<2>'.  The buffer name is recorded when you create
+;;  a bookmark.  If you later use same-buffer cycling then the
+;;  bookmarks cycled are only those created with the same buffer name
+;;  as the current buffer.
+;;
+;;  This is the reason why the `*-file/buffer*' commands are bound to
+;;  keys.  They are usually what you want.  They try first to work
+;;  with bookmarks for the same file as the current buffer, if it is
+;;  visiting a file.
+ 
+;;(@* "Autonamed Bookmarks - Easy Come Easy Go")
+;; ** "Autonamed Bookmarks - Easy Come Easy Go" **
+;;
+;;  Sometimes it is convenient to quickly create and delete bookmarks
+;;  whose names you don't really care about.  That is the purpose of
+;;  "autonamed" bookmarks.  An autonamed bookmark has a simple name
+;;  provided automatically, and it does not record any region
+;;  information - it records only a position.  An autonamed bookmark
+;;  is nevertheless an ordinary, persistent bookmark.
+;;
+;;  `C-x x RET' creates a bookmark at point without prompting you for
+;;  the name.  It is named using the current buffer name preceded by
+;;  the position in the buffer.  For example, the default name of the
+;;  autonamed bookmark in buffer `foo.el' at position 58356 is
+;;  `000058356 foo.el'.
+;;
+;;  When you jump to any bookmark, the actual destination can differ
+;;  from the recorded position, because the buffer text might have
+;;  changed.  In that case, the position you jump to has been
+;;  automatically relocated using the recorded bookmark context (some
+;;  buffer text surrounding the original position).
+;;
+;;  If option `bmkp-save-new-location-flag' is non-`nil' then, after
+;;  jumping, the recorded position of the bookmark is automatically
+;;  updated to reflect the new location jumped to.  This is true for
+;;  any bookmark.
+;;
+;;  In the case of an autonamed bookmark, the bookmark name typically
+;;  reflects the recorded position when you create it.  And when you
+;;  jump to it, both the name and the recorded position are updated to
+;;  reflect the jump destination.  So jumping to an autonamed bookmark
+;;  keeps its persistent record in sync with the buffer location.
+;;
+;;  You will thus notice that the names of autonamed bookmarks can
+;;  change as you visit them (e.g. cycling).  The bookmarks are
+;;  automatically repositioned following their recorded contexts, and
+;;  their names reflect that repositioning.
+;;
+;;  It is only when you jump to a bookmark that it is repositioned
+;;  this way, and only if needed.  It is normal that some bookmarks
+;;  become somewhat out of sync with their original positions as you
+;;  edit the text in the buffer.  In addition, if you highlight
+;;  bookmarks then you will notice the highlighting move as you edit
+;;  nearby text.  The recorded bookmark has not changed, but its
+;;  highlight has moved.  The highlight moves more or less as if it
+;;  were an Emacs marker. When you jump to the bookmark and it is thus
+;;  updated, the highlight moves back to the recorded position,
+;;  adjusted perhaps to fit the recorded context.
+;;
+;;  `C-x x RET' is `bmkp-toggle-autonamed-bookmark-set/delete', and it
+;;  does double duty.  If an autonamed bookmark is under the cursor,
+;;  then `C-x x RET' deletes it.  Easy creation, easy deletion.
+;;  Because of this toggle behavior, there is at most one autonamed
+;;  bookmark at any given buffer position.
+;;
+;;  `C-x x RET' has a third use: With a prefix argument, it prompts
+;;  you to confirm the deletion of *ALL* autonamed bookmarks for the
+;;  current buffer.
+;;
+;;  (You can also use `C-x x delete' (that's the `delete' key), bound
+;;  to `bmkp-delete-bookmarks', to delete individual bookmarks under
+;;  the cursor or all bookmarks in the buffer.  This is not limited to
+;;  autonamed bookmarks.)
+;;
+;;  In addition to `C-x x RET', you can create autonamed bookmarks
+;;  using these commands:
+;;
+;;  * `bmkp-set-autonamed-bookmark-at-line' - At a line beginning
+;;  * `bmkp-set-autonamed-regexp-buffer'    - At buffer matches
+;;  * `bmkp-set-autonamed-regexp-region'    - At region matches
+;;  * `bmkp-occur-create-autonamed-bookmarks' (`C-c b' in `*Occur*') -
+;;    At `occur' and `multi-occur' hits
+;;
+;;  Autonamed bookmarks are normal bookmarks.  In particular, they are
+;;  persisted.  If you do not care to persist them, you can ensure
+;;  that they are automatically deleted by adding
+;;  `bmkp-delete-autonamed-this-buffer-no-confirm' to
+;;  `kill-buffer-hook' and `bmkp-delete-autonamed-no-confirm' to
+;;  `kill-emacs-hook':
+;;
+;;    (add-hook 'kill-buffer-hook
+;;              'bmkp-delete-autonamed-this-buffer-no-confirm)
+;;    (add-hook 'kill-emacs-hook
+;;              'bmkp-delete-autonamed-no-confirm)
+;;
+;;  You can customize the format of autonamed bookmarks using options
+;;  `bmkp-autoname-bookmark-function' and `bmkp-autoname-format'.
+;;
+;;  For example, if you want autonamed bookmarks to show the line and
+;;  column numbers, in the form `L<num>,C<num> <buffer>', where <num>
+;;  is a sequence of decimal digits and <buffer> is the buffer name,
+;;  then you can use a function such as this as the value of
+;;  `bmkp-autoname-bookmark-function':
+;;
+;;    (defun my-auto-l+c-name (position)
+;;      "Return a name for POSITION that uses line & column numbers."
+;;      (let ((line  (line-number-at-pos position))
+;;            (col   (save-excursion
+;;                     (goto-char position) (current-column))))
+;;        (format "L%d,C%d %s" col line (buffer-name))))
+;;
+;;  To enable Bookmark+ to recognize such bookmarks as autonamed, you
+;;  would then set `bmkp-autoname-format' to the format specification
+;;  "^L[0-9]+,C[0-9]+ %B", to match their names.  Here, the `%B' is a
+;;  Bookmark+ format specifier that corresponds to the buffer name.
+;;
+;;  Recognizing the buffer name in an autonamed bookmark is important
+;;  or commands that act only on autonamed bookmarks for a specific
+;;  buffer.  That includes commands `bmkp-autonamed-this-buffer-jump'
+;;  and `bmkp-delete-all-autonamed-for-this-buffer'.
+;;
+;;  You use the special format specifier `%B' for the buffer name,
+;;  instead of just `%s', because the format can have multiple `%'
+;;  sequences, and the buffer name could be anywhere in the bookmark
+;;  name.  Depending on the buffer, the buffer name could thus be
+;;  confused with other text in the bookmark name, unless you use `%B'
+;;  to show where it is.  You can use just `%s' for it if there is no
+;;  risk of ambiguity.  (Use `%s' in `bmkp-autoname-bookmark-function'
+;;  to insert the buffer name.)
+ 
+;;(@* "Temporary Bookmarks")
+;;  ** Temporary Bookmarks **
+;;
+;;  Autonamed bookmarks are easy-come-easy-go in the sense that `C-x x
+;;  RET' either sets (creates) one or deletes the one under the
+;;  cursor.  But what about temporary bookmarks in general?  What if
+;;  you want only bookmarks that are temporary, that is, not saved to
+;;  disk?  Or what if you want certain kinds of bookmarks to always be
+;;  temporary?  Or what if you want to toggle whether particular
+;;  bookmarks get saved automatically?
+;;
+;;
+;;(@* "Temporary Bookmarking Mode")
+;;  *** Temporary Bookmarking Mode ***
+;;
+;;  As always, you can control whether the bookmarks in the current
+;;  bookmark list are saved automatically using option
+;;  `bookmark-save-flag'.  Remember that you can toggle this option
+;;  using command `bmkp-toggle-saving-bookmark-file' (bound to `M-~'
+;;  in the bookmark-list buffer).  Remember too that you can at any
+;;  time change the set of available bookmarks (the bookmark list),
+;;  which means also changing the set of bookmarks that are
+;;  susceptible to being saved.
+;;
+;;  You could, for example:
+;;
+;;  1. Use `C-x x 0' (`bmkp-empty-file') to create a new, empty
+;;     bookmark file.
+;;
+;;  2. Use `C-x x L' (`bmkp-switch-bookmark-file-create') to switch to
+;;     using that new, empty bookmark file.
+;;
+;;  3. Use `M-x bmkp-toggle-saving-bookmark-file' to turn off
+;;     auto-saving bookmarks to disk.
+;;
+;;  This is essentially what the minor-mode toggle command
+;;  `bmkp-temporary-bookmarking-mode' does.  When in this minor mode,
+;;  bookmarks that you create are stored on the new bookmark list,
+;;  which is not automatically saved to disk.  If you do not
+;;  explicitly save it yourself then the bookmarks are lost when your
+;;  Emacs session ends - they are only temporary.
+;;
+;;  This command is bound to `M-L' in the bookmark-list display buffer
+;;  (`*Bookmark List*').  The suffix `L' indicates that this has to do
+;;  with loading a bookmark file.  See (@> "Using Multiple Bookmark Files").
+;;
+;;  In the bookmark-list display, temporary bookmarking mode is
+;;  indicated in the mode line by `TEMPORARY Bookmarking' in place of
+;;  `Bookmarks' as the mode name.
+;;
+;;
+;;(@* "Making Bookmarks Temporary")
+;;  *** Making Bookmarks Temporary ***
+;;
+;;  Instead of simply switching to a temporary bookmark list, so that
+;;  *all* bookmarking is only temporary, you more often want to have
+;;  some bookmarks be temporary while still ensuring that others get
+;;  saved.  Or you temporarily want all new bookmarks that you create
+;;  and all bookmarks that you update to be temporary, without
+;;  affecting other, unchanged bookmarks.
+;;
+;;  You can control this at the level of individual bookmarks, types
+;;  of bookmarks, or all bookmarks whenever they are set (created or
+;;  updated).
+;;
+;;  * At the individual-bookmark level, commands
+;;    `bmkp-make-bookmark-temporary' and `bmkp-make-bookmark-savable'
+;;    prompt you for a bookmark name and then set its
+;;    temporary/savable status.  Command
+;;    `bmkp-toggle-temporary-bookmark' combines these commands,
+;;    toggling the status for a given bookmark.
+;;
+;;    In the bookmark list, this toggle is bound to `C-M-X'.  There
+;;    are also commands in the bookmark-list display to toggle the
+;;    temporary/savable status of the marked bookmarks (`M-X'), to
+;;    mark the temporary bookmarks (`X M'), and to show only the
+;;    temporary bookmarks (`X S').
+;;
+;;  * At the bookmark-type level, you can customize user option
+;;    `bmkp-autotemp-bookmark-predicates'.  It is a list of bookmark
+;;    predicates - typically type predicates - that define which
+;;    bookmarks are automatically made temporary whenever they are
+;;    set.
+;;
+;;    The default value includes the type predicates for autonamed
+;;    bookmarks: `bmkp-autonamed-bookmark-p' and
+;;    `bmkp-autonamed-this-buffer-bookmark-p'.  This means that (only)
+;;    autonamed bookmarks are made temporary whenever they are created
+;;    or updated.
+;;
+;;    The doc string for the option lists the predefined bookmark type
+;;    predicates, but you can use any bookmark predicates.
+;;
+;;  * Finally, you can toggle whether *all* bookmarks become temporary
+;;    whenever they are created or updated, using command
+;;    `bmkp-toggle-autotemp-on-set', which is bound globally to `C-x x
+;;    x'.
+;;
+;;  You can delete all such temporary bookmarks from the current
+;;  bookmark list using command `bmkp-delete-all-temporary-bookmarks'
+;;  (or by using `X M' to mark them in the bookmark-list display and
+;;  then hitting `D' to delete thems).
+;;
+;;  In the bookmark-list display (buffer `*Bookmark List*'), temporary
+;;  bookmarks are indicated with the mark `X' in the same column where
+;;  the annotation mark `a' would otherwise appear.
+ 
+;;(@* "Automatic Bookmarking")
+;;  ** Automatic Bookmarking **
+;;
+;;  You might find automatic bookmarking useful.  The idea is that
+;;  Emacs sets a bookmark for you automatically.
+;;
+;;  Bookmark+ can do this either when you perform some action (besides
+;;  explicitly bookmarking) or whenever you are idle for a given
+;;  period of time (option `bmkp-automatic-bookmark-mode-delay').
+;;
+;;
+;;(@* "Automatic Bookmarking Using a Hook")
+;;  *** Automatic Bookmarking Using a Hook ***
+;;
+;;  To automatically set a bookmark whenever some hook is run, put
+;;  function `bmkp-set-automatic-bookmark' on the hook.  For example,
+;;  to set a bookmark at a definition jumped to whenever you use
+;;  Imenu, you can do this:
+;;
+;;  (add-hook 'imenu-after-jump-hook #'bmkp-set-automatic-bookmark)
+;;
+;;  The bookmark is an autonamed bookmark (see
+;;  (@> "Autonamed Bookmarks - Easy Come Easy Go")).
+;;
+;;
+;;(@* "Automatic Idle-Period Bookmarking")
+;;  *** Automatic Idle-Period Bookmarking ***
+;;
+;;  Automatic idle-period bookmarking creates bookmarks at spots where
+;;  you spend some time (idly).  It uses
+;;  `bmkp-set-automatic-bookmark', so the bookmarks created are
+;;  autonamed (see (@> "Autonamed Bookmarks - Easy Come Easy Go")).
+;;
+;;  How many such bookmarks would you want?  And how close together?
+;;  Bookmark+ tries to provide some user options that let you get the
+;;  behavior you want.  Except for
+;;  `bmkp-automatic-bookmark-mode-delay' they apply to
+;;  `bmkp-set-automatic-bookmark', so they affect both idle-period
+;;  bookmarking and automatic bookmarking on a hook.
+;;
+;;  In general, you probably don't want such bookmarks to be created
+;;  too often or too close together.  You probably don't care about
+;;  the names of the bookmarks created, and you don't want to be
+;;  interrupted to have to name them.  You probably want automatic
+;;  idle-period bookmarking to be per-buffer, but you might sometimes
+;;  want to turn it on or off for all buffers.  You might want more
+;;  than one automatic bookmark on a given line, but probably not.
+;;  Finally, you might or might not want such bookmarks to be
+;;  temporary (current session only) or highlighted.
+;;
+;;  Mode `bmkp-automatic-bookmark-mode' is a local minor mode, which
+;;  means that it is buffer-specific.  The command of the same name
+;;  turns the mode on and off.  When the mode is on, the minor-mode
+;;  indicator ("lighter") `Auto-Bmk' is shown in the mode line for the
+;;  buffer.  You can customize this indicator (removing it, if you
+;;  like), using option `bmkp-automatic-bookmark-mode-lighter'.
+;;
+;;  Command `bmkp-global-automatic-bookmark-mode' turns on the mode in
+;;  all buffers, that is, it is global, not local.  Regardless of
+;;  whether you use the mode locally or globally, a bookmark is
+;;  created automatically only in the current buffer.  That is, a
+;;  buffer must be current (selected) for an automatic bookmark to be
+;;  created there - it's not enough that the mode be enabled in the
+;;  buffer.
+;;
+;;  Option `bmkp-automatic-bookmark-set-function' defines the
+;;  bookmark-setting function.  By default, its value is
+;;  `bmkp-set-autonamed-bookmark-at-line', which sets an autonamed
+;;  bookmark at (the beginning of) the current line.  If you want
+;;  bookmarks to be created automatically then you typically want them
+;;  to be autonamed, both because the name is unimportant and because
+;;  setting an autonamed bookmark requires no interaction on your
+;;  part.  But you can use any setting function you like as the option
+;;  value.  (You can always rename an autonamed bookmark later, if you
+;;  want to keep it and give it a meaningful name.)
+;;
+;;  Option `bmkp-automatic-bookmark-min-distance' is the minimum
+;;  number of characters between automatic bookmark positions.  If the
+;;  cursor is currently closer to some existing automatically created
+;;  bookmark, then no automatic bookmark is set at point.  If you set
+;;  this to `nil' then there is no limit on how close the bookmarks
+;;  can be.  (But there is only one autonamed bookmark at any given
+;;  position.)
+;;
+;;  If you want automatically created bookmarks to be temporary (not
+;;  saved to your bookmark file), then customize option
+;;  `bmkp-autotemp-bookmark-predicates' so that it includes the kind
+;;  of bookmarks that are set by
+;;  `bmkp-automatic-bookmark-set-function'.  For example, if automatic
+;;  bookmarking sets autonamed bookmarks, then
+;;  `bmkp-autotemp-bookmark-predicates' should include
+;;  `bmkp-autonamed-bookmark-p' or
+;;  `bmkp-autonamed-this-buffer-bookmark-p' (it includes both of these
+;;  by default).  Remember that you can toggle whether a given
+;;  bookmark is temporary or savable, using `M-X' in the bookmark-list
+;;  display (buffer `*Bookmark List*').
+;;
+;;  If you want the bookmarks to be automatically highlighted, then
+;;  customize option `bmkp-auto-light-when-set' to highlight bookmarks
+;;  of the appropriate kind.  For example, to highlight autonamed
+;;  bookmarks set it to `autonamed-bookmark'.
+;;
+;;  NOTE: If you use Emacs 20, then by default
+;;  `bmkp-automatic-bookmark-mode' is global rather than local.  The
+;;  doc string tells you how to make it local instead.  If you use
+;;  Emacs 21, then `bmkp-automatic-bookmark-mode' is local but there
+;;  is no global mode, `bmkp-global-automatic-bookmark-mode'.  This is
+;;  because Emacs 21 does not support `define-globalized-minor-mode'.
+;;
+;;
+;;(@* "Automatic Info Bookmarking")
+;;  *** Automatic Info Bookmarking ***
+;;
+;;  If you enable global minor mode `bmkp-info-auto-bookmark-mode',
+;;  each Info node you visit is bookmarked automatically, using the
+;;  default bookmark name, which is the Info manual name plus the node
+;;  name.  For example, node `Lisp Data Types' in the Elisp manual
+;;  gives you a bookmark named `(elisp) Lisp Data Types'.
+;;
+;;  With the mode enabled, when you visit an Info node an existing
+;;  bookmark with the same name is always updated.  If no such
+;;  bookmark exists then a new one is created, provided option
+;;  `bmkp-info-auto-type' has value `create-or-replace'.  If it has
+;;  value `update-only' then no new bookmark is created.  The default
+;;  option value is `update-only'.  You can toggle the value using
+;;  command `bmkp-toggle-info-auto-type'.
+;;
+;;  With `bmkp-info-auto-bookmark-mode' enabled, even if you have
+;;  created Info bookmarks with the default names manually, they are
+;;  updated automatically.  In particular, updating a bookmark
+;;  increments the recorded number of visits to the Info node and the
+;;  time of the last visit.
+;;
+;;  You can sort bookmarks in the bookmark-list display by the time of
+;;  last visit, using `s d', or by the number of visits, using `s v'.
+;;
+;;  This gives you an easy way to see which parts of the manuals you
+;;  have visited most recently and how much you have visited them.
+;;  Showing only Info bookmarks gives you the effect of a persistent
+;;  mini-manual of just the visited Info nodes.  Turn the mode off
+;;  anytime you do not want to record Info visits.
+;;
+;;  Also useful in this context, though not related to bookmarking, is
+;;  the ability to save your Info history persistently, so links to
+;;  visited nodes are shown using a different face.  This makes it
+;;  easy to see which parts of a manual you have already looked at.
+;;  (And checking a bookmark to a visited node shows you how much you
+;;  have visited it.)
+;;
+;;  If you use library `info+.el' then you have this complementary
+;;  ability save your Info history list persistently.  Just enable
+;;  minor mode `Info-persist-history-mode'.
+ 
+;;(@* "Highlighting Bookmark Locations")
+;;  ** Highlighting Bookmark Locations **
+;;
+;;  You can highlight the location (destination) of a bookmark.  For
+;;  this feature you need library `bookmark+-lit.el' in addition to
+;;  the other Bookmark+ libraries.
+;;
+;;  You might never want to highlight a bookmark, or you might want to
+;;  highlight most or even all bookmarks, or your use of highlighting
+;;  might fall somewhere between.  It depends on what kind of
+;;  bookmarks you have and how you use them.  Bookmark+ lets you
+;;  choose.  By default, no bookmarks are highlighted.
+ 
+;;(@* "Defining How to Highlight")
+;;  ** Defining How to Highlight **
+;;
+;;  By default, autonamed bookmarks are highlighted differently from
+;;  non-autonamed bookmarks.  Bookmark highlighting uses a style and a
+;;  face.  The available styles are these:
+;;
+;;  * Region              - Highlight the region, if a region bookmark
+;;  * Line                - Highlight line of the bookmark position
+;;  * Position            - Highlight character at bookmark position
+;;  * Line Beginning      - Highlight first character on line
+;;  * Left Fringe         - Highlight only the left fringe
+;;  * Left Fringe + Line  - Highlight the left fringe and the line
+;;  * Right Fringe        - Highlight only the right fringe
+;;  * Right Fringe + Line - Highlight the right fringe and the line
+;;
+;;  You can customize the default styles and faces to use for
+;;  autonamed and non-autonamed bookmarks.  You can also customize the
+;;  fringe bitmaps to use.
+;;
+;;  * `bmkp-light-autonamed'                  (face)
+;;  * `bmkp-light-non-autonamed'              (face)
+;;  * `bmkp-light-autonamed-region'           (face)
+;;  * `bmkp-light-non-autonamed-region'       (face)
+;;  * `bmkp-light-style-autonamed'            (option)
+;;  * `bmkp-light-style-non-autonamed'        (option)
+;;  * `bmkp-light-style-autonamed-region'     (option)
+;;  * `bmkp-light-style-non-autonamed-region' (option)
+;;  * `bmkp-light-left-fringe-bitmap'         (option)
+;;  * `bmkp-light-right-fringe-bitmap'        (option)
+;;
+;;  Note: A region, position, or line highlight acts more or less like
+;;  an Emacs marker: it moves with the surrounding text.  As you edit
+;;  the text in the buffer, the highlighted location can thus become
+;;  out of sync with the recorded position.  This is normal.  When you
+;;  jump to the bookmark, its highlight is automatically repositioned
+;;  to the recorded location, possibly adjusted according to the
+;;  surrounding context.
+;;
+;;  In addition to the default highlighting, which you can customize,
+;;  you can set the highlighting for individual bookmarks and
+;;  particular sets of bookmarks (overriding their default
+;;  highlighting).  These individual settings are saved as part of the
+;;  bookmarks themselves.
+;;
+;;  In the bookmark list display (buffer `*Bookmark List*'):
+;;
+;;  * `H +'    - Set the highlighting for this line's bookmark
+;;  * `H > +'  - Set the highlighting for the marked bookmarks
+;;
+;;  Globally, you can use `M-x bmkp-set-lighting-for-bookmark' to set
+;;  the highlighting for a given bookmark.
+;;
+;;  Each of these commands prompts you (with completion) for the style
+;;  and face to set, as well as for a condition that controls whether
+;;  to highlight.  Each of these is optional - just hit `RET' (empty
+;;  input) at its prompt to skip setting it.
+;;
+;;  The condition is an Emacs-Lisp sexp that is evaluated whenever an
+;;  attempt is made to highlight the bookmark.  Any resulting value
+;;  except `:no-light' highlights the bookmark.  The sexp can refer to
+;;  the variables `this-bookmark' and `this-bookmark-name', whose
+;;  values are the bookmark to be highlighted and its name,
+;;  respectively.
+;;
+;;  So, for example, if you wanted to be prompted each time before
+;;  highlighting a certain bookmark you might set its highlighting
+;;  condition to a sexp such as this:
+;;
+;;  (or (y-or-n-p (format "Highlight `%s' " this-bookmark-name))
+;;      :no-light)
+;;
+;;  If you hit `n' at the prompt then `:no-light' is returned and the
+;;  bookmark is not highlighted.
+;;
+;;  In the bookmark-list display, a pink-background, one-character
+;;  highlight is used next to each bookmark that has a highlight
+;;  override wrt the default.  You can see what that override setting
+;;  is by using `C-u C-h RET' - look for the `lighting' entry in the
+;;  bookmark definition.
+;;
+;;
+;;(@* "Highlighting On Demand")
+;;  *** Highlighting On Demand ***
+;;
+;;  You can highlight or unhighlight a bookmark or a set of bookmarks
+;;  on demand.
+;;
+;;  In the bookmark list (buffer `*Bookmark List*'):
+;;
+;;  * `H H',   `H U'   - Highlight, unhighlight this line's bookmark
+;;
+;;  * `H > H', `H > U' - Highlight, unhighlight the marked bookmarks
+;;
+;;  Globally:
+;;
+;;  * `C-x x C-u'          - Unhighlight a highlighted bookmark at
+;;                           point or on the same line (in that order)
+;;
+;;  * `C-x x h', `C-x x u' - Highlight, unhighlight a bookmark in the
+;;                           current buffer (with completion).
+;;
+;;  * `C-x x H', `C-x x U' - Highlight, unhighlight bookmarks:
+;;
+;;                           With plain `C-u': all bookmarks
+;;
+;;                           With `C-u C-u': navigation-list bookmarks
+;;
+;;                           Otherwise, bookmarks in current buffer:
+;;                            No prefix arg:  all bookmarks
+;;                            Prefix arg > 0: autonamed bookmarks
+;;                                       < 0: non-autonamed bookmarks
+;;
+;;  The default bookmark for `C-x x u' is the same bookmark that is
+;;  unhighlighted by `C-x x C-u': a (highlighted) bookmark at point
+;;  (preferably) or on the same line.  The latter key binding just
+;;  saves you having to hit `RET' to pick the default.
+;;
+;;  When you use `C-x x h', you can use a prefix argument to override
+;;  both the default highlighting and any highlighting that is
+;;  recorded for the bookmark itself.  You are prompted for the style
+;;  or face to use:
+;;
+;;  * Negative arg:     prompted for style
+;;  * Non-negative arg: prompted for face
+;;  * Plain `C-u':      prompted for style and face
+;;
+;;
+;;(@* "Highlighting Automatically")
+;;  *** Highlighting Automatically ***
+;;
+;;  You can also highlight automatically, whenever you set (create) a
+;;  bookmark or jump to one.  This is controlled by these options:
+;;
+;;  * `bmkp-auto-light-when-set'
+;;  * `bmkp-auto-light-when-jump'
+;;
+;;  You can choose any of these values for either option:
+;;
+;;  * Autonamed bookmark
+;;  * Non-autonamed bookmark
+;;  * Any bookmark
+;;  * Autonamed bookmarks in buffer
+;;  * Non-autonamed bookmarks in buffer
+;;  * All bookmarks in buffer
+;;  * None (no automatic highlighting) - the default
+;;
+;;  The first three values highlight only the bookmark being set or
+;;  jumped to.
+;;
+;;  Be aware that, depending on the setting, highlighting can take a
+;;  while.
+ 
+;;(@* "Using Highlighted Bookmarks")
+;;  ** Using Highlighted Bookmarks **
+;;
+;;  Once you have highlighted bookmarks, what can you do with them?
+;;  Obviously, the highlighting can help you distinguish and find
+;;  bookmarks visually.  But highlighting also serves as yet another
+;;  way to define sets: the highlighted vs unhighlighted bookmarks.
+;;
+;;  Any command that operates on a set of bookmarks can be applied to
+;;  one or the other of these two sets.  Bookmark+ defines only a few
+;;  such operations, but you can easily define others.
+;;
+;;  In addition to such specific commands, you can also apply general
+;;  operations to the highlighted or unhighlighted bookmarks, using
+;;  the bookmark-list display (`*Bookmark List*').  `H S' shows only
+;;  the bookmarks that are currently highlighted, and `H M' marks
+;;  them.  You can then perform any of the available bookmark-list
+;;  operations on them.
+;;
+;;  Globally, you can use these keys:
+;;
+;;  * `C-x x ='                    - List the bookmarks that are
+;;                                   highlighted at point.  With a
+;;                                   prefix arg, show the full data.
+;;
+;;  * `C-x j h', `C-x 4 j h'       - Jump to a highlighted bookmark.
+;;                                   Only highlighted bookmarks are
+;;                                   completion candidates.
+;;
+;;  * `C-x x C-down', `C-x x C-up' - Cycle to the next and previous
+;;                                   highlighted bookmark.
+ 
+;;(@* "Bookmark Links")
+;;  ** Bookmark Links **
+;;
+;;  You can use command `bmkp-insert-bookmark-link' to create links in
+;;  any Emacs text that jump to particular bookmarks when you follow
+;;  them (by hitting `RET' or clicking `mouse-2').  If you hit `?' or
+;;  double-click `mouse-1' on such a bookmark link then the bookmark
+;;  is described, showing the same information as `C-h M'
+;;  (`bmkp-describe-bookmark').
+;;
+;;  You are prompted for the bookmark to link.  If the region is
+;;  active and nonempty then the link is put on its text.  Otherwise,
+;;  you are prompted for the link text, which is inserted.  The
+;;  default link text is the bookmark name in this case.
+;;
+;;  The bookmark linked can be of any type.
+;;
+;;  This simple feature lets you easily create "launching pads" for
+;;  different sets of bookmarks: buffers or files that consist of
+;;  bookmark links and any other text you like.  This gives you yet
+;;  another way to organize bookmarks (and so also the files,
+;;  directories, etc. that they target).
+;;
+;;  If you also use library `font-lock+.el' then the links appear with
+;;  face `link', even in a font-locked buffer.  (Library
+;;  `font-lock+.el' just provides this feature of allowing
+;;  non-font-lock highlighting in a font-locked buffer.  See
+;;  https://lists.gnu.org/archive/html/emacs-devel/2014-08/msg00540.html.)
+;;
+;;  The links you create this way are not persistent, but you can of
+;;  course re-create them using Lisp.
+;;
+;;
+;;(@* "Org Mode Links that Jump To Bookmarks")
+;;  *** Org Mode Links that Jump To Bookmarks ***
+;;
+;;  You can also easily define Org-mode links that jump to bookmarks.
+;;  These links are persistent.  Again, the bookmark linked can be of
+;;  any type.
+;;
+;;  You can use the standard Org command `org-store-link' (`C-c l') in
+;;  buffer `*Bookmark List*' to store a link to the bookmark at point.
+;;  (This is also item `Store Org Link' in the mouse-3 popup menu.)
+;;
+;;  Outside buffer `*Bookmark List*' you can use command
+;;  `bmkp-store-org-link' to store a link to any bookmark.  You are
+;;  prompted for the bookmark name.  You can even enter the name of a
+;;  bookmark that does not yet exist.  (This is also item `Store Org
+;;  Link To...' on menu `Bookmarks'.)
+;;
+;;  If you use a numeric prefix arg with either command then the
+;;  bookmark link stored will be for jumping to the bookmark in the
+;;  same window.  Without a numeric prefix arg, the link will use
+;;  another window.  (Org mode defines other behaviors for non-numeric
+;;  prefix args, such as `C-u C-u'.)
+;;
+;;  As usual, to insert a bookmark link, you use command
+;;  `org-insert-link'.  Enter the name of the target bookmark at the
+;;  prompt.  In Org mode you can use the usual Org key bindings to
+;;  follow the link.  In any mode you can use standard Org command
+;;  `org-open-at-point-global' (not bound to a key by default).
+ 
+;;(@* "Bookmark Menus")
+;;  ** Bookmark Menus **
+;;
+;;  Two menu-bar menus for Bookmark+ have already been mentioned:
+;;
+;;  * Menu `Bookmark+', for the bookmark-list display (buffer
+;;    `*Bookmark List*').
+;;
+;;  * Menu `Bookmarks', which is typically a submenu of the menu-bar
+;;    `Edit' menu (available also with vanilla Emacs but enhanced by
+;;    Bookmark+).
+;;
+;;  Access to bookmarks for the currently visited file or current
+;;  buffer is available as a `Bookmarks Here' submenu of the
+;;  major-mode menu-bar menu in modes Info and Buffer-Menu, if option
+;;  `bmkp-add-bookmarks-here-menu-flag' is non-`nil'.
+;;
+;;  The menu items let you cycle among bookmarks in the current
+;;  file/buffer or access the bookmark-list display for only those
+;;  bookmarks.
+;;
+;;  If you use library Dired+ then the same access is available in
+;;  Dired mode on menu-bar menu `Dir' > `Bookmark' > `Here'.
+;;
+;;  If you use library Imenu+ then the same access is available in an
+;;  Imenu submenu `Bookmarks Here'.  In this case there are also menu
+;;  items to jump to each bookmark in the file/buffer.  For Imenu,
+;;  display of the menu is controlled by option
+;;  `imenup-show-bookmarks-flag'.
+ 
+;;(@* "Use Bookmark+ with Icicles")
+;;  ** Use Bookmark+ with Icicles **
+;;
+;;  `Icicles' (https://www.emacswiki.org/emacs/Icicles) enhances your
+;;  use of Bookmark+ in several ways.
+;;
+;;  When jumping to a bookmark, you can narrow the completion
+;;  candidates to bookmarks of a particular type (e.g. Info, using
+;;  `C-M-i'; remote, using `C-M-@'; region, using `C-M-r').  You can
+;;  narrow again (and again), to another bookmark type, to get the
+;;  intersection (e.g. remote Info bookmarks that define a region).
+;;
+;;  You can also narrow against different bookmark-name patterns
+;;  (e.g. regexps) - so-called "progressive completion".  And take the
+;;  complement (e.g., bookmarks whose names do not match
+;;  `foo.*2010.*bar').  (This is not special to bookmarks; it is
+;;  standard `Icicles' practice.)
+;;
+;;  In Icicle mode, several of the Bookmark+ keys are remapped to
+;;  corresponding `Icicles' multi-commands.  A bookmark jump key thus
+;;  becomes a bookmarks browser.  For example, `C-x j d' browses among
+;;  any number of Dired bookmarks.
+;;
+;;  A single key can set a bookmark or visit bookmarks.  This key is
+;;  whatever command `bmkp-bookmark-set-confirm-overwrite' would
+;;  normally be bound to - e.g. `C-x r m'.  A prefix arg controls what
+;;  it does.  If negative (`M--'), jump to (browse) bookmarks.
+;;  Otherwise, set a bookmark using
+;;  `bmkp-bookmark-set-confirm-overwrite', as follows:
+;;
+;;  * No prefix arg: Prompt for the bookmark name.  The candidates are
+;;    bookmarks in the current buffer (or all bookmarks if there are
+;;    none in the current buffer).
+;;
+;;  * (Non-negative) numeric prefix arg: No prompt.  Use the buffer
+;;    name plus the text of the region (if active) or the current line
+;;    as the bookmark name.  Quickest way to set a bookmark.
+;;
+;;  * Plain `C-u': Prompt for name, no bookmark overwrite.
+;;
+;;  During completion of a bookmark name, many features of the
+;;  bookmark-list display (see (@> "The Bookmark List Display")) are
+;;  available on the fly.  Buffer `*Completions*' acts like a dynamic
+;;  version of `*Bookmark List*':
+;;
+;;  * Candidates are highlighted in the `*Completions*' window
+;;    according to their bookmark type.
+;;
+;;  * Candidates are `Icicles' multi-completions with up to three
+;;    parts:
+;;
+;;     a. the bookmark name
+;;     b. the bookmark file or buffer name
+;;     c. any tags
+;;
+;;    You can match any or all of the parts.  For example, you can
+;;    match bookmarks that have tags by typing this regexp:
+;;
+;;    C-M-j . * C-M-j S-TAB
+;;
+;;    Each `C-M-j' inserts `^G\n', which is `icicle-list-join-string',
+;;    the string used to join the parts.  This regexp says, "match the
+;;    completion candidates that have all three parts (two join
+;;    strings)", hence some tags.
+;;
+;;    You can turn off the use of multi-completion candidates for
+;;    subsequent commands, so only bookmark names are used, by hitting
+;;    `M-m' in the minibuffer.  You can think of this as similar to
+;;    using `M-t' in `*Bookmark List*' to toggle showing file names.
+;;    You can make not showing files and tags the default behavior by
+;;    customizing `icicle-show-multi-completion-flag'.
+;;
+;;  * You can sort completion candidates using the Bookmark+ sort
+;;    orders.  Use `C-,' to cycle among sort orders.
+;;
+;;  * You can use `Icicles' candidate-help keys (`C-M-RET',
+;;    `C-M-down', etc.) to get detailed information about the current
+;;    bookmark candidate.  `C-u C-M-RET' shows the complete, internal
+;;    info defining the bookmark.  And without doing anything, summary
+;;    info about the current candidate is available in the mode line
+;;    of buffer `*Completions*'.
+;;
+;;  * You can use `Icicles' candidate-action keys (`C-RET',
+;;    `C-mouse-2', `C-down', etc.) to visit any number of bookmarks.
+;;    For example, holding down `C-down' cycles among the current
+;;    bookmark candidates, opening each in turn.
+;;
+;;  * You can use `S-delete' to delete the bookmark named by the
+;;    current candidate.  You can delete any number of bookmarks this
+;;    way, during a single invocation of a bookmark command.
+;;
+;;  * You can define `Icicles' sets of bookmarks, persistent or not,
+;;    and act on their members in various ways.
+;;
+;;  During file-name completion, you can do any of the following on
+;;  the fly:
+;;
+;;  * Jump to one or more file bookmarks, using `C-x m'.
+;;
+;;  * Create one or more autofile bookmarks, using `C-x a a'.
+;;
+;;  * Add tags to one or more files or directories (autofile
+;;    bookmarks), using `C-x a +'.
+;;
+;;  * Remove tags from one or more files or directories (autofile
+;;    bookmarks), using `C-x a -'.
+;;
+;;  There are 25 Icicles commands for searching bookmark destinations!
+;;  The most general is `icicle-search-bookmark'.  Others let you
+;;  search specific kinds of bookmarks, or bookmarks having various
+;;  combinations of tags.
+;;
+;;  During Icicles search (of anything, not just a bookmark
+;;  destination), you can save sets of completion candidates, which
+;;  means sets of search hits, as bookmarks.  And Icicles lets you use
+;;  set operations (complement, union, intersection, difference etc.)
+;;  on the current set of search hits.
+;;
+;;  When you "jump" to an Icicles search-hits bookmark, its recorded
+;;  search hits are restored to Icicles search as completion
+;;  candidates, either replacing the current candidates or adding to
+;;  them.
+;;
+;;  You can thus save and later return to different sets of search
+;;  results using different bookmarks.  You can "jump" to an Icicles
+;;  search-hits bookmark during any Icicles search, whether you search
+;;  a file, a buffer, multiple files, or multiple buffers.
+ 
+;;(@* "Bookmark Compatibility with Vanilla Emacs (`bookmark.el')")
+;;  ** Bookmark Compatibility with Vanilla Emacs (`bookmark.el') **
+;;
+;;  Bookmark+ is generally compatible with GNU Emacs versions 20 and
+;;  later.  You can use bookmarks with Bookmark+ regardless of whether
+;;  they were created using Bookmark+ or vanilla Emacs (i.e., library
+;;  `bookmark.el').
+;;
+;;  But for best results, if you have bookmarks that you created using
+;;  Bookmark+ then use Bookmark+, not vanilla Emacs, to access them.
+;;  This section provides details.
+;;
+;;  Set user option `bmkp-propertize-bookmark-names-flag', depending
+;;  on your usage scenario (the default is `t' for Emacs 21 and later,
+;;  `nil' for Emacs 20):
+;;
+;;  1. Set it to `nil' if you will often be going back and forth
+;;     between using Bookmark+ and using vanilla Emacs.  (Do this also
+;;     if you use Emacs 20.)
+;;
+;;  2. Set it to non-`nil' if you instead always use only Bookmark+
+;;     (with Emacs 21 or later), or you use vanilla Emacs only to jump
+;;     to bookmarks but never to update or create bookmarks.
+;;
+;;  #1 is VERY IMPORTANT.  You can lose data if you do not respect it.
+;;
+;;  The reason for rule #1 is this: When the option is non-`nil'
+;;  Bookmark+ writes bookmarks to your bookmark file in a format that
+;;  can be read and used by vanilla Emacs (21 and later) but which
+;;  vanilla Emacs then saves as unreadable.  If the option value is
+;;  `nil' there is no such problem.
+;;
+;;  #2 is not a requirement.  It is just a good idea, to be able to
+;;  take better advantage of Bookmark+.  If you set the option to
+;;  `nil' then you cannot use multiple bookmarks that have the same
+;;  name.  Vanilla Emacs does not make good use of such critters, but
+;;  Bookmark+ does.  Having multiple bookmarks with the same name is
+;;  particularly useful for autofiles.  It means you can have
+;;  different autofiles in different directories but with the same
+;;  name.  See (@> "Autofile Bookmarks").
+;;
+;;  Here is what happens when `bmkp-propertize-bookmark-names-flag' is
+;;  non-nil:
+;;
+;;  Besides its name, which is what you see and use most of the time,
+;;  a bookmark contains other information such as the target location,
+;;  textual context hints, and last access time.  Non-`nil'
+;;  `bmkp-propertize-bookmark-names-flag' has no effect on vanilla
+;;  Emacs, but it causes Bookmark+ to put the full bookmark
+;;  information on the bookmark name as a text property.
+;;
+;;  The name thus encapsulates all of the information contained in the
+;;  full bookmark of which it is part.  Knowing the name is then
+;;  enough to know everything about the bookmark.  Part of the
+;;  bookmark (its name) refers to the whole of it.  In Lisp this
+;;  self-reference is implemented using circular structures.
+;;
+;;  When Bookmark+ saves such circular structures to your bookmark
+;;  file, if the option is non-`nil' then it takes care to do so in
+;;  such a way that they can be read in again when your bookmark file
+;;  is loaded.  In Lisp terms, it binds `print-circle' to non-`nil'
+;;  when it writes your bookmarks.  If the option value is `nil' then
+;;  the circularity (self-reference) is removed before your bookmarks
+;;  are saved.  Either way, the file is readable.
+;;
+;;  Vanilla Emacs (21 and later) has no problem reading your bookmark
+;;  file if it contains such circular structures.  But if you then use
+;;  it to save the file again, the Lisp code it writes has invalid
+;;  Lisp `read' syntax (because it does not remove the circularity but
+;;  it also does not bind `print-circle' to non-`nil').
+;;
+;;  If that happens, the result is a bookmark file that is UNREADABLE.
+;;  It cannot be loaded into either vanilla Emacs or Bookmark+.  If
+;;  you do not have an uncorrupted backup version of the file to
+;;  revert to, then you will need to edit it by hand to clean it up.
+;;
+;;  So do not let that happen to you!  For best results use only
+;;  Bookmark+ to access bookmarks created using Bookmark+.
+;;
+;;  If you must use vanilla Emacs with your bookmarks, then make sure
+;;  they are not saved by Bookmark+ with the option non-`nil': Using
+;;  Bookmark+, set the option to `nil' and then save the file.
+;;
+;;  That is:
+;;
+;;  1. `M-x set-variable bmkp-propertize-bookmark-names-flag nil',
+;;     to stop using propertized bookmark names.
+;;  2. `C-x x e' or `C-x r l', to display the bookmark list.
+;;  3. `g', to refresh the display.
+;;  4. `S', to save the bookmark list.
+;;  5. `M-x bmkp-save-menu-list-state', to save the display state.
+;;
+;;  Then you can use your bookmark file with vanilla Emacs (but
+;;  without the possibility of having multiple bookmarks with the same
+;;  name).
+;;
+;;  Note that when the option value is non-`nil', propertized bookmark
+;;  names are saved not only to your bookmark file but also to any
+;;  full snapshots you create of the bookmark-list display state using
+;;  command `bmkp-bmenu-define-full-snapshot-command' (`C-c C-C', aka
+;;  `C-c C-S-c').  See (@> "State-Restoring Commands and Bookmarks").
+ 
+;;(@* "New Bookmark Structure")
+;;  ** New Bookmark Structure **
+;;
+;;  The bookmark data structure, variable `bookmark-alist', has been
+;;  enhanced to support new bookmark types.  For a description of this
+;;  enhanced structure, use `C-h v bookmark-alist'.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+;; You need not load this file.  It contains only documentation.
+
+(provide 'bookmark+-doc)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; bookmark+-doc.el ends here
+
diff --git a/lisp/bookmark+-key.el b/lisp/bookmark+-key.el
new file mode 100644 (file)
index 0000000..bc8e707
--- /dev/null
@@ -0,0 +1,1474 @@
+;;; bookmark+-key.el --- Bookmark+ key and menu bindings.
+;;
+;; Filename: bookmark+-key.el
+;; Description: Bookmark+ key and menu bindings.
+;; Author: Drew Adams
+;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com")
+;; Copyright (C) 2010-2022, Drew Adams, all rights reserved.
+;; Created: Fri Apr  1 15:34:50 2011 (-0700)
+;; Last-Updated: Fri Jan 14 12:49:18 2022 (-0800)
+;;           By: dradams
+;;     Update #: 980
+;; URL: https://www.emacswiki.org/emacs/download/bookmark%2b-key.el
+;; Doc URL: https://www.emacswiki.org/emacs/BookmarkPlus
+;; Keywords: bookmarks, bookmark+, placeholders, annotations, search, info, url, eww, w3m, gnus
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x, 24.x, 25.x, 26.x
+;;
+;; Features that might be required by this library:
+;;
+;;   None
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;    The Bookmark+ libraries are these:
+;;
+;;    `bookmark+.el'     - main (driver) library
+;;    `bookmark+-mac.el' - Lisp macros
+;;    `bookmark+-lit.el' - (optional) code for highlighting bookmarks
+;;    `bookmark+-bmu.el' - code for the `*Bookmark List*' (bmenu)
+;;    `bookmark+-1.el'   - other (non-bmenu) required code
+;;    `bookmark+-key.el' - key and menu bindings (this file)
+;;
+;;    `bookmark+-doc.el' - documentation (comment-only file)
+;;    `bookmark+-chg.el' - change log (comment-only file)
+;;
+;;    The documentation (in `bookmark+-doc.el') includes how to
+;;    byte-compile and install Bookmark+.  The documentation is also
+;;    available in these ways:
+;;
+;;    1. From the bookmark list (`C-x r l'):
+;;       Use `?' to show the current bookmark-list status and general
+;;       help, then click link `Doc in Commentary' or link `Doc on the
+;;       Web'.
+;;
+;;    2. From the Emacs-Wiki Web site:
+;;       https://www.emacswiki.org/emacs/BookmarkPlus.
+;;
+;;    3. From the Bookmark+ group customization buffer:
+;;       `M-x customize-group bookmark-plus', then click link
+;;       `Commentary'.
+;;
+;;    (The commentary links in #1 and #3 work only if you have library
+;;    `bookmark+-doc.el' in your `load-path'.)
+;;
+;;
+;;  User options defined here:
+;;
+;;    `bmkp-add-bookmarks-here-menu-flag',
+;;    `bmkp-bookmark-map-prefix-key', `bmkp-jump-map-prefix-key',
+;;    `bmkp-jump-other-window-map-prefix-key'.
+;;
+;;  Non-interactive functions defined here:
+;;
+;;    `bmkp-bookmark-data-from-record',
+;;    `bmkp-bookmark-name-from-record',
+;;    `bmkp-exists-bookmark-satisfying-p',
+;;    `bmkp-exists-this-file/buffer-bookmarks-p',
+;;    `bmkp-set-map-prefix-key', `bookmark-name-from-full-record',
+;;    `bookmark-name-from-record'.
+;;
+;;  Internal variables defined here:
+;;
+;;    `bmkp-annotate-map', `bmkp-annotate-menu', `bmkp-here-menu',
+;;    `bmkp-bookmarks-here-menu-command-entries',
+;;    `bmkp-find-file-menu', `bmkp-highlight-menu', `bmkp-jump-map',
+;;    `bmkp-jump-menu', `bmkp-jump-other-window-map',
+;;    `bmkp-jump-tags-menu', `bmkp-set-map', `bmkp-tags-map',
+;;    `bmkp-tags-menu'.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; *This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 3, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;
+
+(eval-when-compile
+ (or (condition-case nil
+         (load-library "bookmark+-mac") ; Use load-library to ensure latest .elc.
+       (error nil))
+     (require 'bookmark+-mac)))         ; Require, so can load separately if not on `load-path'.
+;; bmkp-menu-bar-make-toggle
+
+(eval-when-compile (require 'cl)) ;; case
+
+;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Quiet the byte-compiler
+
+(defvar bmkp-bmenu-buffer) ; In `bookmark+.el'
+(defvar grep-mode-map)
+
+
+;; Prefix keys.
+;;
+;; These two maps are always on `bookmark-map', wherever it is: `bmkp-set-map', `bmkp-tags-map'.
+;;
+(defun bmkp-set-map-prefix-key (pref-keys-option keys)
+  "Set prefix key option SYMBOL to key-sequence VALUE."
+  (set pref-keys-option keys)
+  (let* ((g-map     (current-global-map))
+         (b-map     (case pref-keys-option
+                      (bmkp-bookmark-map-prefix-keys          'bookmark-map)
+                      (bmkp-jump-map-prefix-keys              'bmkp-jump-map)
+                      (bmkp-jump-other-window-map-prefix-keys 'bmkp-jump-other-window-map))))
+    (dolist (key  (where-is-internal b-map g-map))
+      (define-key g-map key nil))
+    (dolist (key  keys)
+      (define-key g-map key b-map))))
+
+(defcustom bmkp-bookmark-map-prefix-keys (list (kbd "C-x x"))
+  "Prefix keys for `bookmark-map' in `current-global-map'.
+Each value of the list is a prefix key bound to keymap `bookmark-map'."
+  :type (if (> emacs-major-version 21)
+            '(repeat (key-sequence :tag "Key" :value [ignore]))
+          '(repeat (restricted-sexp
+                    :tag "Key"
+                    :match-alternatives ((lambda (x) (or (stringp x)  (vectorp x))))
+                    :value [ignore])))
+  :set 'bmkp-set-map-prefix-key
+  :group 'bookmark-plus)
+
+(defcustom bmkp-jump-map-prefix-keys (list (kbd "C-x j"))
+  "Prefix keys for `bmkp-jump-map' in `current-global-map'.
+Each value of the list is a prefix key bound to keymap
+`bmkp-jump-map'."
+  :type (if (> emacs-major-version 21)
+            '(repeat (key-sequence :tag "Key" :value [ignore]))
+          '(repeat (restricted-sexp
+                    :tag "Key"
+                    :match-alternatives ((lambda (x) (or (stringp x)  (vectorp x))))
+                    :value [ignore])))
+  :set 'bmkp-set-map-prefix-key
+  :group 'bookmark-plus)
+
+(defcustom bmkp-jump-other-window-map-prefix-keys (list (kbd "C-x 4 j"))
+  "Prefix keys for `bmkp-jump-other-window-map' in `current-global-map'.
+Each value of the list is a prefix key bound to keymap
+`bmkp-jump-other-window-map'."
+  :type (if (> emacs-major-version 21)
+            '(repeat (key-sequence :tag "Key" :value [ignore]))
+          '(repeat (restricted-sexp
+                    :tag "Key"
+                    :match-alternatives ((lambda (x) (or (stringp x)  (vectorp x))))
+                    :value [ignore])))
+  :set 'bmkp-set-map-prefix-key
+  :group 'bookmark-plus)
+
+(defcustom bmkp-add-bookmarks-here-menu-flag nil
+  "Non-nil means add a `Bookmarks Here' menu to some menu-bar menus.
+The menu is added only if there are in fact bookmarks for the current
+buffer or file.  The default value is nil because checking whether
+there are such bookmarks can take a little time."
+  :type 'boolean :group 'bookmark-plus)
+
+
+
+;; Some general Renamings.
+;;
+;; 1. Fix incompatibility introduced by gratuitous Emacs name change.
+;;
+(cond ((and (fboundp 'bookmark-name-from-record)  (not (fboundp 'bookmark-name-from-full-record)))
+       (defalias 'bookmark-name-from-full-record 'bookmark-name-from-record))
+      ((and (fboundp 'bookmark-name-from-full-record)  (not (fboundp 'bookmark-name-from-record)))
+       (defalias 'bookmark-name-from-record 'bookmark-name-from-full-record)))
+
+;; 2. The vanilla name of the first is misleading, as it returns only the cdr of the record.
+;;    The second is for consistency.
+;;
+(defalias 'bmkp-bookmark-data-from-record 'bookmark-get-bookmark-record)
+(defalias 'bmkp-bookmark-name-from-record 'bookmark-name-from-full-record)
+
+
+;; Quiet the byte-compiler
+(defvar bmkp-bmenu-menubar-menu)        ; In `bookmark+-bmu.el'.
+(defvar bmkp-bmenu-toggle-menu)         ; In `bookmark+-bmu.el'.
+(defvar bmkp-crosshairs-flag)           ; In `bookmark+-1.el'.
+(defvar bmkp-eww-replace-keys-flag)     ; In `bookmark+-1.el' (Emacs 25+).
+(defvar bmkp-prompt-for-tags-flag)      ; In `bookmark+-1.el'.
+(defvar bmkp-save-new-location-flag)    ; In `bookmark+-1.el'.
+(defvar diredp-bookmark-menu)           ; In `dired+.el'.
+(defvar eww-mode-map)                   ; In `eww.el' (Emacs 24.4+).
+(defvar gnus-summary-mode-map)          ; In `gnus-sum.el'.
+(defvar Info-mode-map)                  ; In `info.el'.
+(defvar Info-mode-menu)                 ; In `info.el'.
+(defvar Man-mode-map)                   ; In `man.el'.
+(defvar mouse-wheel-down-event)         ; In `mwheel.el'.
+(defvar mouse-wheel-up-event)           ; In `mwheel.el'.
+(defvar w3m-minor-mode-map)             ; In `w3m.el'.
+(defvar w3m-mode-map)                   ; In `w3m.el'.
+(defvar woman-menu)                     ; In `woman.el'.
+(defvar woman-mode-map)                 ; In `woman.el'.
+ 
+;;(@* "Keymaps")
+;;; Keymaps ----------------------------------------------------------
+
+;; `help-map'
+(define-key help-map "M"  'bmkp-describe-bookmark)
+
+;; `bookmark-map'
+
+;; (define-key ctl-x-map "x" bookmark-map)
+;; (define-key ctl-x-map "xj" 'bookmark-jump-other-window)               ; `C-x x j' (also `C-x 4 j j')
+(define-key ctl-x-map "rK" 'bmkp-set-desktop-bookmark)        ; `C-x r K' (also `C-x x K', `C-x x c K')
+
+(define-key bookmark-map "0"      'bmkp-empty-file)                                   ; `C-x x 0'
+(define-key bookmark-map "2"      'bmkp-clone-bookmark)                               ; `C-x x 2'
+(define-key bookmark-map "5"      'bookmark-jump-other-frame)                         ; `C-x x 5'
+(define-key bookmark-map "B"      'bmkp-choose-navlist-from-bookmark-list)            ; `C-x x B'
+;; `e' is `edit-bookmarks' (aka `bookmark-bmenu-list', from vanilla Emacs.
+(define-key bookmark-map "E"      'bmkp-edit-bookmark-record)                         ; `C-x x E'
+;; The original `bookmark-insert-location' in `bookmark.el' was `f'.
+(define-key bookmark-map "I"      'bookmark-insert-location)                          ; `C-x x I'
+(define-key bookmark-map "\C-j"   'bmkp-jump-to-list)                                 ; `C-x x C-j'
+(define-key bookmark-map "K"      'bmkp-set-desktop-bookmark) ; `C-x x K' (also `C-x r K', `C-x x c K')
+(define-key bookmark-map "L"      'bmkp-switch-bookmark-file-create)                  ; `C-x x L'
+(define-key bookmark-map "\C-l"   'bmkp-switch-to-bookmark-file-this-file/buffer)     ; `C-x x C-l'
+(define-key bookmark-map "m"      'bmkp-bookmark-set-confirm-overwrite)               ; `C-x x m'
+(define-key bookmark-map "N"      'bmkp-navlist-bmenu-list)                           ; `C-x x N'
+(define-key bookmark-map "o"      'bookmark-jump-other-window)           ; `C-x x o' (also `C-x 4 j j')
+(define-key bookmark-map "q"      'bookmark-jump-other-window)           ; `C-x x q' (also `C-x 4 j j')
+(define-key bookmark-map "r"      'bmkp-edit-bookmark-name-and-location)              ; `C-x x r'
+(define-key bookmark-map "\C-s"   'bmkp-save-bookmarks-this-file/buffer)              ; `C-x x C-s'
+(define-key bookmark-map "\M-w"   'bmkp-set-snippet-bookmark)        ; `C-x x M-w' (also `C-x x c M-w')
+(define-key bookmark-map "x"      'bmkp-toggle-autotemp-on-set)                       ; `C-x x x'
+(define-key bookmark-map "y"      'bmkp-set-bookmark-file-bookmark)                   ; `C-x x y'
+(when (featurep 'bookmark+-lit)
+  (define-key bookmark-map "h"    'bmkp-light-bookmark-this-buffer)                   ; `C-x x h'
+  (define-key bookmark-map "H"    'bmkp-light-bookmarks)                              ; `C-x x H'
+  (define-key bookmark-map "u"    'bmkp-unlight-bookmark-this-buffer)                 ; `C-x x u'
+  (define-key bookmark-map "U"    'bmkp-unlight-bookmarks)                            ; `C-x x U'
+  (define-key bookmark-map "\C-u" 'bmkp-unlight-bookmark-here)                        ; `C-x x C-u'
+  (define-key bookmark-map "="    'bmkp-bookmarks-lighted-at-point))                  ; `C-x x ='
+(define-key bookmark-map ","      'bmkp-this-file/buffer-bmenu-list)                  ; `C-x x ,'
+(define-key bookmark-map "?"      'bmkp-describe-bookmark-lighted-here)               ; `C-x x ?'
+(define-key bookmark-map ":"      'bmkp-choose-navlist-of-type)                       ; `C-x x :'
+(define-key bookmark-map "\r"     'bmkp-toggle-autonamed-bookmark-set/delete)         ; `C-x x RET'
+(define-key bookmark-map [delete] 'bmkp-delete-bookmarks)                             ; `C-x x delete'
+
+(substitute-key-definition 'kill-line 'bmkp-delete-bookmarks          ; `C-x x C-k', `C-x x deleteline'
+                           bookmark-map (current-global-map))
+(define-key bookmark-map [deletechar] 'bmkp-delete-bookmarks)                      ; `C-x x deletechar'
+;; For Mac Book:
+(define-key bookmark-map [kp-delete] 'bmkp-delete-bookmarks)                        ; `C-x x kp-delete'
+
+;; If you use Emacs before Emacs 22, then you will want to bind the commands
+;; whose names do *not* end in `-repeat' to keys that are easily repeatable.
+;; For example, you might want to bind `bmkp-next-bookmark-this-file/buffer'
+;; (not `bmkp-next-bookmark-this-file/buffer-repeat') to a key such as [f2].
+;;
+(when (> emacs-major-version 21)
+  (define-key bookmark-map "n"          'bmkp-next-bookmark-this-file/buffer-repeat) ; `C-x x n'
+  (define-key bookmark-map "\C-n"       'bmkp-next-bookmark-this-file/buffer-repeat) ; `C-x x C-n'
+  (define-key bookmark-map [down]       'bmkp-next-bookmark-this-file/buffer-repeat) ; `C-x x down'
+  (put 'bmkp-next-bookmark-this-file/buffer-repeat :advertised-binding (kbd "C-x x <down>"))
+
+  ;; This requires the fix for Emacs bug #6256, which is in Emacs 23.3 (presumably).
+  ;; For older Emacs versions you can bind the wheel event to `bmkp-next-bookmark-this-file/buffer'
+  ;; in the global map.  IOW, prior to Emacs 23.3 a mouse event won't work with `repeat'.
+  (when (and (boundp 'mouse-wheel-up-event)
+             (or (> emacs-major-version 23)
+                 (and (= emacs-major-version 23)  (> emacs-minor-version 2))))
+    (define-key bookmark-map (vector (list mouse-wheel-up-event))
+      'bmkp-next-bookmark-this-file/buffer-repeat))                            ; `C-x x mouse-wheel-up'
+  (define-key bookmark-map "p"          'bmkp-previous-bookmark-this-file/buffer-repeat) ; `C-x x p'
+  (define-key bookmark-map "\C-p"       'bmkp-previous-bookmark-this-file/buffer-repeat) ; `C-x x C-p'
+  (define-key bookmark-map [up]         'bmkp-previous-bookmark-this-file/buffer-repeat) ; `C-x x up'
+  (put 'bmkp-previous-bookmark-this-file/buffer-repeat :advertised-binding (kbd "C-x x <up>"))
+
+  ;; This requires the fix for Emacs bug #6256, which is in Emacs 23.3 (presumably).
+  ;; For older Emacs versions you can bind the wheel event to `bmkp-previous-bookmark-this-file/buffer'
+  ;; in the global map.  IOW, prior to Emacs 23.3 a mouse event won't work with `repeat'.
+  (when (and (boundp 'mouse-wheel-down-event)
+             (or (> emacs-major-version 23)
+                 (and (= emacs-major-version 23)  (> emacs-minor-version 2))))
+    (define-key bookmark-map (vector (list mouse-wheel-down-event))
+      'bmkp-previous-bookmark-this-file/buffer-repeat))                      ; `C-x x mouse-wheel-down'
+  (define-key bookmark-map "f"          'bmkp-next-bookmark-repeat)                  ; `C-x x f'
+  (define-key bookmark-map "\C-f"       'bmkp-next-bookmark-repeat)                  ; `C-x x C-f'
+  (define-key bookmark-map [right]      'bmkp-next-bookmark-repeat)                  ; `C-x x right'
+  (put 'bmkp-next-bookmark-repeat :advertised-binding (kbd "C-x x <right>"))
+  (define-key bookmark-map "b"          'bmkp-previous-bookmark-repeat)              ; `C-x x b'
+  (define-key bookmark-map "\C-b"       'bmkp-previous-bookmark-repeat)              ; `C-x x C-b'
+  (define-key bookmark-map [left]       'bmkp-previous-bookmark-repeat)              ; `C-x x left'
+  (put 'bmkp-previous-bookmark-repeat :advertised-binding (kbd "C-x x <left>"))
+  (define-key bookmark-map [next]       'bmkp-next-bookmark-w32-repeat)              ; `C-x x next'
+  (define-key bookmark-map [prior]      'bmkp-previous-bookmark-w32-repeat)          ; `C-x x prior'
+  (when (featurep 'bookmark+-lit)
+    (define-key bookmark-map [C-down]   'bmkp-next-lighted-this-buffer-repeat)       ; `C-x x C-down'
+    (define-key bookmark-map [C-up]     'bmkp-previous-lighted-this-buffer-repeat))) ; `C-x x C-up'
+
+
+;; `bmkp-annotate-map': prefix `C-x x a'
+
+(defvar bmkp-annotate-map nil "Keymap containing bindings for bookmark annotation commands.")
+
+(define-prefix-command 'bmkp-annotate-map)
+(define-key bookmark-map "a"      bmkp-annotate-map)                           ; `C-x x a' for annotate
+
+(define-key bmkp-annotate-map "a" 'bmkp-annotate-bookmark)                     ; `C-x x a a'
+(define-key bmkp-annotate-map "b" 'bmkp-annotate-bookmark-this-file/buffer)    ; `C-x x a b'
+(define-key bmkp-annotate-map "B" 'bmkp-annotate-all-bookmarks-this-file/buffer) ; `C-x x a B'
+(define-key bmkp-annotate-map "e" 'bookmark-edit-annotation)                   ; `C-x x a e'
+(define-key bmkp-annotate-map "s" 'bookmark-show-annotation)                   ; `C-x x a s'
+(define-key bmkp-annotate-map "S" 'bookmark-show-all-annotations)              ; `C-x x a S'
+
+
+;; `bmkp-set-map': prefix `C-x x c'
+
+(defvar bmkp-set-map nil "Keymap containing bindings for bookmark set commands.")
+
+(define-prefix-command 'bmkp-set-map)
+(define-key bookmark-map "c"    bmkp-set-map)                                  ; `C-x x c' for create
+
+(define-key bmkp-set-map "a"    'bmkp-autofile-set)                            ; `C-x x c a'
+(define-key bmkp-set-map "f"    'bmkp-file-target-set)                         ; `C-x x c f'
+(define-key bmkp-set-map "F"    'bmkp-make-function-bookmark)                  ; `C-x x c F'
+(define-key bmkp-set-map "K"    'bmkp-set-desktop-bookmark)                    ; `C-x x c K'
+(define-key bmkp-set-map "\C-k" 'bmkp-wrap-bookmark-with-last-kbd-macro)       ; `C-x x C-k'
+(define-key bmkp-set-map "m"    'bmkp-bookmark-set-confirm-overwrite)          ; `C-x x c m'
+(define-key bmkp-set-map "M"    'bookmark-set)                                 ; `C-x x c M'
+(define-key bmkp-set-map "s"    'bmkp-set-sequence-bookmark)                   ; `C-x x c s'
+(define-key bmkp-set-map "u"    'bmkp-url-target-set)                          ; `C-x x c u'
+(define-key bmkp-set-map "\M-w" 'bmkp-set-snippet-bookmark)                    ; `C-x x c M-w'
+(define-key bmkp-set-map "y"    'bmkp-set-bookmark-file-bookmark)              ; `C-x x c y'
+(define-key bmkp-set-map "\r"   'bmkp-toggle-autonamed-bookmark-set/delete)    ; `C-x x c RET'
+
+
+;; Add set commands to other keymaps: occur, compilation: `C-c C-b', `C-c C-M-b', `C-c C-M-B'.
+;; See `dired+.el' for Dired bookmarking keys, which are different.
+
+(add-hook 'occur-mode-hook
+          (lambda ()
+            (unless (lookup-key occur-mode-map "\C-c\C-b")
+              (define-key occur-mode-map "\C-c\C-b" 'bmkp-occur-target-set)) ; `C-c C-b'
+            (unless (lookup-key occur-mode-map "\C-c\C-\M-b")
+              (define-key occur-mode-map "\C-c\C-\M-b" 'bmkp-occur-target-set-all)) ; `C-c C-M-b'
+            (unless (lookup-key occur-mode-map [(control ?c) (control meta shift ?b)])
+              (define-key occur-mode-map [(control ?c) (control meta shift ?b)]
+                'bmkp-occur-create-autonamed-bookmarks)))) ; `C-c C-M-B' (aka `C-c C-M-S-b')
+
+(when (fboundp 'bmkp-compilation-target-set) ; Emacs 22+
+
+  (add-hook 'compilation-mode-hook
+            (lambda ()
+              (unless (lookup-key compilation-mode-map "\C-c\C-b")
+                (define-key compilation-mode-map "\C-c\C-b" 'bmkp-compilation-target-set)) ; `C-c C-b'
+              (unless (lookup-key compilation-mode-map "\C-c\C-\M-b") ; `C-c C-M-b'
+                (define-key compilation-mode-map "\C-c\C-\M-b" 'bmkp-compilation-target-set-all))))
+
+  (when (fboundp 'compilation-minor-mode) ; Emacs 26+
+
+    (add-hook
+     'grep-mode-hook
+     (lambda ()
+       (unless (lookup-key grep-mode-map "\C-c\C-b")
+         (define-key grep-mode-map "\C-c\C-b" 'bmkp-compilation-target-set)) ; `C-c C-b'
+       (unless (lookup-key grep-mode-map "\C-c\C-\M-b") ; `C-c C-M-b'
+         (define-key grep-mode-map "\C-c\C-\M-b" 'bmkp-compilation-target-set-all))))
+
+    (add-hook
+     'compilation-minor-mode-hook
+     (lambda ()
+       (unless (lookup-key compilation-minor-mode-map "\C-c\C-b")
+         (define-key compilation-minor-mode-map "\C-c\C-b" 'bmkp-compilation-target-set)) ; `C-c C-b'
+       (unless (lookup-key compilation-minor-mode-map "\C-c\C-\M-b") ; `C-c C-M-b'
+         (define-key compilation-minor-mode-map "\C-c\C-\M-b" 'bmkp-compilation-target-set-all))))
+
+    (add-hook
+     'compilation-shell-minor-mode-hook
+     (lambda ()
+       (unless (lookup-key compilation-shell-minor-mode-map "\C-c\C-b")
+         (define-key compilation-shell-minor-mode-map
+           "\C-c\C-b" 'bmkp-compilation-target-set)) ; `C-c C-b'
+       (unless (lookup-key compilation-shell-minor-mode-map "\C-c\C-\M-b") ; `C-c C-M-b'
+         (define-key compilation-shell-minor-mode-map
+           "\C-c\C-\M-b" 'bmkp-compilation-target-set-all))))))
+
+
+;; `bmkp-tags-map': prefix `C-x x t'
+
+(defvar bmkp-tags-map nil "Keymap containing bindings for bookmark tag commands.")
+
+(define-prefix-command 'bmkp-tags-map)
+(define-key bookmark-map "t"  bmkp-tags-map)                                      ; `C-x x t' for tags
+
+(define-key bmkp-tags-map "0"    'bmkp-remove-all-tags)                           ; `C-x x t 0'
+(define-key bmkp-tags-map "+"    nil) ; For Emacs 20
+(define-key bmkp-tags-map "+b"   'bmkp-add-tags)                                  ; `C-x x t + b'
+(define-key bmkp-tags-map "-b"   'bmkp-remove-tags)                               ; `C-x x t - b'
+(define-key bmkp-tags-map "+a"   'bmkp-tag-a-file)                                ; `C-x x t + a'
+(define-key bmkp-tags-map "-a"   'bmkp-untag-a-file)                              ; `C-x x t - a'
+(define-key bmkp-tags-map "c"    'bmkp-copy-tags)                                 ; `C-x x t c'
+(define-key bmkp-tags-map "d"    'bmkp-remove-tags-from-all)                      ; `C-x x t d'
+(define-key bmkp-tags-map "e"    'bmkp-edit-tags)                                 ; `C-x x t e'
+(define-key bmkp-tags-map "l"    'bmkp-list-all-tags)                             ; `C-x x t l'
+(define-key bmkp-tags-map "p"    'bmkp-paste-add-tags)                            ; `C-x x t p'
+(define-key bmkp-tags-map "q"    'bmkp-paste-replace-tags)                        ; `C-x x t q'
+(define-key bmkp-tags-map "r"    'bmkp-rename-tag)                                ; `C-x x t r'
+(define-key bmkp-tags-map "v"    'bmkp-set-tag-value)                             ; `C-x x t v'
+(define-key bmkp-tags-map "V"    'bmkp-set-tag-value-for-navlist)                 ; `C-x x t V'
+(define-key bmkp-tags-map "\M-w" 'bmkp-copy-tags)                                 ; `C-x x t M-w'
+(define-key bmkp-tags-map "\C-y" 'bmkp-paste-add-tags)                            ; `C-x x t C-y'
+
+
+;; `bmkp-jump-map' and `bmkp-jump-other-window-map': prefixes `C-x j' and `C-x 4 j'
+
+(defvar bmkp-jump-map nil "Keymap containing bindings for bookmark jump commands.")
+
+(defvar bmkp-jump-other-window-map nil
+  "Keymap containing bindings for bookmark jump other-window commands.")
+
+(define-prefix-command 'bmkp-jump-map)
+(define-prefix-command 'bmkp-jump-other-window-map)
+;; (define-key ctl-x-map   "j" bmkp-jump-map)
+;; (define-key ctl-x-4-map "j" bmkp-jump-other-window-map)
+(define-key bookmark-bmenu-mode-map "j"  nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "J"  nil) ; For Emacs 20
+(define-key bookmark-bmenu-mode-map "J"  bmkp-jump-map)
+(define-key bookmark-bmenu-mode-map "j"  bmkp-jump-other-window-map)
+(define-key bookmark-bmenu-mode-map "j>" 'bmkp-bmenu-jump-to-marked)                           ; `j >'
+
+(define-key ctl-x-5-map                "B"    'bookmark-jump-other-frame)       ; `C-x j 5', `C-x 5 B'
+(define-key bmkp-jump-map              "5"    'bookmark-jump-other-frame )                     ; `J 5'
+(define-key bmkp-jump-map              "."    nil) ; For Emacs 20
+(define-key bmkp-jump-other-window-map "."    nil) ; For Emacs 20
+(define-key bmkp-jump-map              ".d"   'bmkp-dired-this-dir-jump)                 ; `C-x j . d'
+(define-key bmkp-jump-other-window-map ".d"   'bmkp-dired-this-dir-jump-other-window)  ; `C-x 4 j . d'
+(define-key bmkp-jump-map              ".f"   'bmkp-file-this-dir-jump)                  ; `C-x j . f'
+(define-key bmkp-jump-other-window-map ".f"   'bmkp-file-this-dir-jump-other-window)   ; `C-x 4 j . f'
+
+(define-key bmkp-jump-map              ","    nil) ; For Emacs 20
+(define-key bmkp-jump-other-window-map ","    nil) ; For Emacs 20
+(define-key bmkp-jump-map              ",,"   'bmkp-this-buffer-jump)                    ; `C-x j , ,'
+(define-key bmkp-jump-other-window-map ",,"   'bmkp-this-buffer-jump-other-window)     ; `C-x 4 j , ,'
+(define-key bmkp-jump-map              ",#"   'bmkp-autonamed-this-buffer-jump)          ; `C-x j , #'
+(define-key bmkp-jump-other-window-map ",#"
+  'bmkp-autonamed-this-buffer-jump-other-window)                                       ; `C-x 4 j , #'
+
+(define-key bmkp-jump-map              "#"    'bmkp-autonamed-jump)                        ; `C-x j #'
+(define-key bmkp-jump-other-window-map "#"    'bmkp-autonamed-jump-other-window)         ; `C-x 4 j #'
+
+(define-key bmkp-jump-map              "="    nil) ; For Emacs 20
+(define-key bmkp-jump-other-window-map "="    nil) ; For Emacs 20
+(define-key bmkp-jump-map              "=b"   'bmkp-specific-buffers-jump)                ; `C-x j = b'
+(define-key bmkp-jump-other-window-map "=b"   'bmkp-specific-buffers-jump-other-window) ; `C-x 4 j = b'
+(define-key bmkp-jump-map              "=f"   'bmkp-specific-files-jump)                  ; `C-x j = f'
+(define-key bmkp-jump-other-window-map "=f"   'bmkp-specific-files-jump-other-window)   ; `C-x 4 j = f'
+
+(define-key bmkp-jump-map              "a"    'bmkp-autofile-jump)                          ; `C-x j a'
+(define-key bmkp-jump-other-window-map "a"    'bmkp-autofile-jump-other-window)           ; `C-x 4 j a'
+(define-key bmkp-jump-map              "b"    'bmkp-non-file-jump)                          ; `C-x j b'
+(define-key bmkp-jump-other-window-map "b"    'bmkp-non-file-jump-other-window)           ; `C-x 4 j b'
+(define-key bmkp-jump-map              "B"    'bmkp-bookmark-list-jump)                     ; `C-x j B'
+(define-key bmkp-jump-other-window-map "B"    'bmkp-bookmark-list-jump)     ; SAME COMMAND: `C-x 4 j B'
+(define-key bmkp-jump-map              "d"    'bmkp-dired-jump)                             ; `C-x j d'
+(define-key bmkp-jump-other-window-map "d"    'bmkp-dired-jump-other-window)              ; `C-x 4 j d'
+
+(eval-after-load "eww"
+  '(when (> emacs-major-version 24)     ; Emacs 25+
+    (when bmkp-eww-replace-keys-flag
+      (bmkp-remap 'eww-add-bookmark       'bookmark-set                eww-mode-map)
+      (bmkp-remap 'eww-list-bookmarks     'bookmark-bmenu-list         eww-mode-map)
+      (bmkp-remap 'eww-next-bookmark      'bmkp-next-url-bookmark  eww-mode-map)
+      (bmkp-remap 'eww-previous-bookmark  'bmkp-previous-url-bookmark  eww-mode-map))
+    (define-key bmkp-jump-map              "e"  'bmkp-eww-jump)                             ; `C-x j e'
+    (define-key bmkp-jump-other-window-map "e"  'bmkp-eww-jump-other-window)))            ; `C-x 4 j e'
+
+(define-key bmkp-jump-map              "f"    'bmkp-file-jump)                              ; `C-x j f'
+(define-key bmkp-jump-other-window-map "f"    'bmkp-file-jump-other-window)               ; `C-x 4 j f'
+(define-key bmkp-jump-map              "\C-f" 'bmkp-find-file)                            ; `C-x j C-f'
+(define-key bmkp-jump-other-window-map "\C-f" 'bmkp-find-file-other-window)             ; `C-x 4 j C-f'
+(define-key bmkp-jump-map              "g"    'bmkp-gnus-jump)                              ; `C-x j g'
+(define-key bmkp-jump-other-window-map "g"    'bmkp-gnus-jump-other-window)               ; `C-x 4 j g'
+(define-key bmkp-jump-map              "h"    'bmkp-lighted-jump)                           ; `C-x j h'
+(define-key bmkp-jump-other-window-map "h"    'bmkp-lighted-jump-other-window)            ; `C-x 4 j h'
+(define-key bmkp-jump-map              "i"    'bmkp-info-jump)                              ; `C-x j i'
+(define-key bmkp-jump-other-window-map "i"    'bmkp-info-jump-other-window)               ; `C-x 4 j i'
+(define-key bmkp-jump-map              "\M-i" 'bmkp-image-jump)                           ; `C-x j M-i'
+(define-key bmkp-jump-other-window-map "\M-i" 'bmkp-image-jump-other-window)            ; `C-x 4 j M-i'
+(define-key bmkp-jump-map              "j"    'bookmark-jump)                               ; `C-x j j'
+(put 'bookmark-jump :advertised-binding "\C-xjj")
+
+(define-key bmkp-jump-other-window-map "j"    'bookmark-jump-other-window)                ; `C-x 4 j j'
+(put 'bookmark-jump-other-window :advertised-binding "\C-x4jj")
+(put 'jump-other :advertised-binding "\C-x4jj")
+
+(define-key bmkp-jump-map              "\C-j" 'bmkp-jump-to-list)                         ; `C-x j C-j'
+(define-key bmkp-jump-map              "K"    'bmkp-desktop-jump)                           ; `C-x j K'
+(define-key bmkp-jump-other-window-map "K"    'bmkp-desktop-jump)           ; SAME COMMAND: `C-x 4 j K'
+(define-key bmkp-jump-map              "l"    'bmkp-local-file-jump)                        ; `C-x j l'
+(define-key bmkp-jump-other-window-map "l"    'bmkp-local-file-jump-other-window)         ; `C-x 4 j l'
+(define-key bmkp-jump-map              "m"    'bmkp-man-jump)                               ; `C-x j m'
+(define-key bmkp-jump-other-window-map "m"    'bmkp-man-jump-other-window)                ; `C-x 4 j m'
+(define-key bmkp-jump-map              "n"    'bmkp-remote-file-jump)         ; `C-x j n' ("_n_etwork")
+(define-key bmkp-jump-other-window-map "n"    'bmkp-remote-file-jump-other-window)        ; `C-x 4 j n'
+(define-key bmkp-jump-map              "N"    'bmkp-jump-in-navlist)                        ; `C-x j N'
+(define-key bmkp-jump-other-window-map "N"    'bmkp-jump-in-navlist-other-window)         ; `C-x 4 j N'
+(define-key bmkp-jump-map              "r"    'bmkp-region-jump)                            ; `C-x j r'
+(define-key bmkp-jump-other-window-map "r"    'bmkp-region-jump-other-window)             ; `C-x 4 j r'
+(define-key bmkp-jump-other-window-map "R"
+  'bmkp-region-jump-narrow-indirect-other-window)                                         ; `C-x 4 j R'
+
+(define-key bmkp-jump-map              "t"    nil) ; For Emacs 20
+(define-key bmkp-jump-other-window-map "t"    nil) ; For Emacs 20
+(define-key bmkp-jump-map              "t*"   'bmkp-all-tags-jump)                        ; `C-x j t *'
+(define-key bmkp-jump-other-window-map "t*"   'bmkp-all-tags-jump-other-window)         ; `C-x 4 j t *'
+(define-key bmkp-jump-map              "t+"   'bmkp-some-tags-jump)                       ; `C-x j t +'
+(define-key bmkp-jump-other-window-map "t+"   'bmkp-some-tags-jump-other-window)        ; `C-x 4 j t +'
+
+(define-key bmkp-jump-map              "t%"   nil) ; For Emacs 20
+(define-key bmkp-jump-other-window-map "t%"   nil) ; For Emacs 20
+(define-key bmkp-jump-map              "t%*"  'bmkp-all-tags-regexp-jump)               ; `C-x j t % *'
+(define-key bmkp-jump-other-window-map "t%*"
+  'bmkp-all-tags-regexp-jump-other-window)                                            ; `C-x 4 j t % *'
+(define-key bmkp-jump-map              "t%+"  'bmkp-some-tags-regexp-jump)              ; `C-x j t % +'
+(define-key bmkp-jump-other-window-map "t%+"
+  'bmkp-some-tags-regexp-jump-other-window)                                           ; `C-x 4 j t % +'
+
+(define-key bmkp-jump-map              "t."   nil) ; For Emacs 20
+(define-key bmkp-jump-other-window-map "t."   nil) ; For Emacs 20
+(define-key bmkp-jump-map              "t.*" 'bmkp-file-this-dir-all-tags-jump)         ; `C-x j t . *'
+(define-key bmkp-jump-other-window-map "t.*"
+  'bmkp-file-this-dir-all-tags-jump-other-window)                                     ; `C-x 4 j t . *'
+(define-key bmkp-jump-map              "t.+" 'bmkp-file-this-dir-some-tags-jump)        ; `C-x j t . +'
+(define-key bmkp-jump-other-window-map "t.+"
+  'bmkp-file-this-dir-some-tags-jump-other-window)                                    ; `C-x 4 j t . +'
+
+(define-key bmkp-jump-map              "t.%" nil) ; For Emacs 20
+(define-key bmkp-jump-other-window-map "t.%" nil) ; For Emacs 20
+(define-key bmkp-jump-map              "t.%*"
+  'bmkp-file-this-dir-all-tags-regexp-jump)                                           ; `C-x j t . % *'
+(define-key bmkp-jump-other-window-map "t.%*"
+  'bmkp-file-this-dir-all-tags-regexp-jump-other-window)                            ; `C-x 4 j t . % *'
+(define-key bmkp-jump-map              "t.%+"
+  'bmkp-file-this-dir-some-tags-regexp-jump)                                          ; `C-x j t . % +'
+(define-key bmkp-jump-other-window-map "t.%+"
+  'bmkp-file-this-dir-some-tags-regexp-jump-other-window)                           ; `C-x 4 j t . % +'
+
+
+(define-key bmkp-jump-map              "ta"   nil) ; For Emacs 20
+(define-key bmkp-jump-other-window-map "ta"   nil) ; For Emacs 20
+(define-key bmkp-jump-map              "ta*"  'bmkp-autofile-all-tags-jump)             ; `C-x j t a *'
+(define-key bmkp-jump-other-window-map "ta*"
+  'bmkp-autofile-all-tags-jump-other-window)                                          ; `C-x 4 j t a *'
+(define-key bmkp-jump-map              "ta+"  'bmkp-autofile-some-tags-jump)            ; `C-x j t a +'
+(define-key bmkp-jump-other-window-map "ta+"
+  'bmkp-autofile-some-tags-jump-other-window)                                         ; `C-x 4 j t a +'
+
+(define-key bmkp-jump-map              "ta%"  nil) ; For Emacs 20
+(define-key bmkp-jump-other-window-map "ta%"  nil) ; For Emacs 20
+(define-key bmkp-jump-map              "ta%*" 'bmkp-autofile-all-tags-regexp-jump)    ; `C-x j t a % *'
+(define-key bmkp-jump-other-window-map "ta%*"
+  'bmkp-autofile-all-tags-regexp-jump-other-window)                                 ; `C-x 4 j t a % *'
+(define-key bmkp-jump-map              "ta%+" 'bmkp-autofile-some-tags-regexp-jump)   ; `C-x j t a % +'
+(define-key bmkp-jump-other-window-map "ta%+"
+  'bmkp-autofile-some-tags-regexp-jump-other-window)                                ; `C-x 4 j t a % +'
+
+(define-key bmkp-jump-map              "tf"   nil) ; For Emacs 20
+(define-key bmkp-jump-other-window-map "tf"   nil) ; For Emacs 20
+(define-key bmkp-jump-map              "tf*"  'bmkp-file-all-tags-jump)                 ; `C-x j t f *'
+(define-key bmkp-jump-other-window-map "tf*"  'bmkp-file-all-tags-jump-other-window)  ; `C-x 4 j t f *'
+(define-key bmkp-jump-map              "tf+"  'bmkp-file-some-tags-jump)                ; `C-x j t f +'
+(define-key bmkp-jump-other-window-map "tf+"  'bmkp-file-some-tags-jump-other-window) ; `C-x 4 j t f +'
+
+(define-key bmkp-jump-map              "tf%"  nil) ; For Emacs 20
+(define-key bmkp-jump-other-window-map "tf%"  nil) ; For Emacs 20
+(define-key bmkp-jump-map              "tf%*" 'bmkp-file-all-tags-regexp-jump)        ; `C-x j t f % *'
+(define-key bmkp-jump-other-window-map "tf%*"
+  'bmkp-file-all-tags-regexp-jump-other-window)                                     ; `C-x 4 j t f % *'
+(define-key bmkp-jump-map              "tf%+" 'bmkp-file-some-tags-regexp-jump)       ; `C-x j t f % +'
+(define-key bmkp-jump-other-window-map "tf%+"
+  'bmkp-file-some-tags-regexp-jump-other-window)                                    ; `C-x 4 j t f % +'
+
+(when (> emacs-major-version 21)        ; Needs `read-file-name' with a PREDICATE arg.
+  (define-key bmkp-jump-map              "t\C-f*" 'bmkp-find-file-all-tags)           ; `C-x j t C-f *'
+  (define-key bmkp-jump-other-window-map "t\C-f*"
+    'bmkp-find-file-all-tags-other-window)                                          ; `C-x 4 j t C-f *'
+  (define-key bmkp-jump-map              "t\C-f+" 'bmkp-find-file-some-tags)          ; `C-x j t C-f +'
+  (define-key bmkp-jump-other-window-map "t\C-f+"
+    'bmkp-find-file-some-tags-other-window)                                         ; `C-x 4 j t C-f +'
+  (define-key bmkp-jump-map              "t\C-f%*" 'bmkp-find-file-all-tags-regexp) ; `C-x j t C-f % *'
+  (define-key bmkp-jump-other-window-map "t\C-f%*"
+    'bmkp-find-file-all-tags-regexp-other-window)                                 ; `C-x 4 j t C-f % *'
+  (define-key bmkp-jump-map              "t\C-f%+"
+    'bmkp-find-file-some-tags-regexp)                                               ; `C-x j t C-f % +'
+  (define-key bmkp-jump-other-window-map "t\C-f%+"
+    'bmkp-find-file-some-tags-regexp-other-window))                               ; `C-x 4 j t C-f % +'
+
+(define-key bmkp-jump-map              "u"    'bmkp-url-jump)                               ; `C-x j u'
+(define-key bmkp-jump-other-window-map "u"    'bmkp-url-jump-other-window)                ; `C-x 4 j u'
+(define-key bmkp-jump-map              "v"    'bmkp-variable-list-jump)                     ; `C-x j v'
+(define-key bmkp-jump-map              "w"    'bmkp-w3m-jump)                               ; `C-x j w'
+(define-key bmkp-jump-other-window-map "w"    'bmkp-w3m-jump-other-window)                ; `C-x 4 j w'
+(define-key bmkp-jump-map              "\M-w" 'bmkp-snippet-to-kill-ring)                 ; `C-x j M-w'
+(define-key bmkp-jump-other-window-map "\M-w" 'bmkp-snippet-to-kill-ring)     ; SAME CMD: `C-x 4 j M-w'
+(define-key bmkp-jump-map              "x"    'bmkp-temporary-jump)                         ; `C-x j x'
+(define-key bmkp-jump-other-window-map "x"    'bmkp-temporary-jump-other-window)          ; `C-x 4 j x'
+(define-key bmkp-jump-map              "y"    'bmkp-bookmark-file-jump)                     ; `C-x j y'
+(define-key bmkp-jump-map              ":"    'bmkp-jump-to-type)                           ; `C-x j :'
+(define-key bmkp-jump-other-window-map ":"    'bmkp-jump-to-type-other-window)            ; `C-x 4 j :'
+
+(defun bmkp-exists-bookmark-satisfying-p (predicate &optional alist)
+  "Return t if there is a bookmark in ALIST that satisfies PREDICATE.
+Else return nil.  ALIST defaults to `bookmark-alist'.
+Put differently, return t iff the filtered alist is non-empty."
+  (catch 'bmkp-exists-bookmark-satisfying-p
+    (dolist (bmk  (or alist  bookmark-alist))
+      (when (funcall predicate bmk) (throw 'bmkp-exists-bookmark-satisfying-p t)))
+    nil))
+
+(defun bmkp-exists-this-file/buffer-bookmarks-p (&optional alist)
+  "Return t if there is a this-file or this-buffer bookmark in ALIST."
+  (bmkp-exists-bookmark-satisfying-p (if (buffer-file-name) #'bmkp-this-file-p #'bmkp-this-buffer-p)))
+
+(defvar bmkp-bookmarks-here-menu-command-entries
+  (list (list 'bmkp-next-bookmark-this-file/buffer-repeat
+             'menu-item
+             "Next Bookmark Here"
+             'bmkp-next-bookmark-this-file/buffer-repeat
+             :help "Jump to the next bookmark in this buffer")
+       (list 'bmkp-previous-bookmark-this-file/buffer-repeat
+             'menu-item
+             "Previous Bookmark Here"
+             'bmkp-previous-bookmark-this-file/buffer-repeat
+             :help "Jump to the previous bookmark in this buffer")
+        (list 'bmkp-here-sep1 'menu-item "--")
+       (list 'bmkp-annotate-bookmark-this-file/buffer
+             'menu-item
+             "Annotate a Bookmark Here"
+             'bmkp-annotate-bookmark-this-file/buffer
+             :help "Annotate a bookmark in this buffer")
+       (list 'bmkp-annotate-all-bookmarks-this-file/buffer
+             'menu-item
+             "Annotate All Bookmarks Here"
+             'bmkp-annotate-all-bookmarks-this-file/buffer
+             :help "Annotate each bookmark in this buffer")
+       (list 'bmkp-edit-bookmark-record-file/buffer
+             'menu-item
+             "Edit a Bookmark Record Here"
+             'bmkp-edit-bookmark-record-file/buffer
+             :help "Edit the full record (Lisp) of a bookmark in this buffer")
+        (list 'bmkp-here-sep2 'menu-item "--")
+        (list 'bmkp-describe-bookmark-lighted-here
+              'menu-item
+              "Describe Highlighted Bookmark This Line (`C-u': internal form)"
+              'bmkp-describe-bookmark-lighted-here
+              :help "Describe a highlighted bookmark on this line.  `C-u': internal description"
+              :enable '(and (fboundp 'bmkp-describe-bookmark-lighted-here)
+                            (or (bmkp-a-bookmark-lighted-at-pos (point) 'FULL)
+                                (bmkp-a-bookmark-lighted-on-this-line 'FULL))))
+        (list 'bmkp-bookmarks-lighted-at-point
+              'menu-item
+              "List Highlighted Bookmarks at Point"
+              'bmkp-bookmarks-lighted-at-point
+              :help "List the bookmarks at point that are highlighted"
+              :enable '(bmkp-bookmarks-lighted-at-point))
+       (list 'bmkp-set-lighting-for-this-buffer
+             'menu-item
+             "Set Highlighting for All Bookmarks Here"
+             'bmkp-set-lighting-for-this-buffer
+             :help "Set the `lighting' entry for all of the bookmarks for this buffer"
+              :visible (featurep 'bookmark+-lit))
+       (list 'bmkp-light-this-buffer
+             'menu-item
+             "Highlight All Bookmarks Here"
+             'bmkp-light-this-buffer
+             :help "Highlight the bookmarks in this buffer"
+              :keys "(C-x x H)" ; Really bound to `bmkp-light-bookmarks'
+              :visible (featurep 'bookmark+-lit))
+       (list 'bmkp-unlight-this-buffer
+             'menu-item
+             "Unhighlight All Bookmarks Here"
+             'bmkp-unlight-this-buffer
+             :help "Highlight the bookmarks in this buffer"
+              :keys "(C-x x U)" ; Really bound to `bmkp-unlight-bookmarks'
+              :visible (featurep 'bookmark+-lit))
+       (list 'bmkp-light-autonamed-this-buffer
+             'menu-item
+             "Highlight Autonamed Bookmarks Here"
+             'bmkp-light-autonamed-this-buffer
+             :help "Highlight the autonamed bookmarks in this buffer"
+              :visible (featurep 'bookmark+-lit))
+       (list 'bmkp-unlight-autonamed-this-buffer
+             'menu-item
+             "Unhighlight Autonamed Bookmarks Here"
+             'bmkp-unlight-autonamed-this-buffer
+             :help "Unhighlight the autonamed bookmarks in this buffer"
+              :visible (featurep 'bookmark+-lit))
+       (list 'bmkp-light-non-autonamed-this-buffer
+             'menu-item
+             "Highlight Non-Autonamed Bookmarks Here"
+             'bmkp-light-non-autonamed-this-buffer
+             :help "Highlight the non-autonamed bookmarks in this buffer"
+              :visible (featurep 'bookmark+-lit))
+       (list 'bmkp-unlight-non-autonamed-this-buffer
+             'menu-item
+             "Unhighlight Non-Autonamed Bookmarks Here"
+             'bmkp-unlight-non-autonamed-this-buffer
+             :help "Unhighlight the non-autonamed bookmarks in this buffer"
+              :visible (featurep 'bookmark+-lit))
+        (list 'bmkp-here-sep3 'menu-item "--")
+       (list 'bmkp-this-file/buffer-bmenu-list
+             'menu-item
+             "Show Bookmark List for Bookmarks Here"
+             'bmkp-this-file/buffer-bmenu-list
+             :help "Show the bookmark list for bookmarks in this buffer")
+        (list 'bmkp-switch-to-bookmark-file-this-file/buffer
+             'menu-item
+             "Switch to Bookmark File for Bookmarks Here..."
+             'bmkp-switch-to-bookmark-file-this-file/buffer
+             :help "Switch to a bookmark file for bookmarks in this buffer")
+       (list 'bmkp-save-bookmarks-this-file/buffer
+             'menu-item
+             "Save Bookmarks Here To Bookmark File..."
+             'bmkp-save-bookmarks-this-file/buffer
+             :help "Save all bookmarks defined for this file/buffer to a file"))
+  "Menu entries for general commands in `Bookmarks' > `Here' menu.")
+
+(progn
+  (defvar bmkp-here-menu (make-sparse-keymap)
+    "`Here' submenu for menu-bar `Bookmarks' menu.
+Menu for bookmarks that target this file or buffer.")
+  (define-prefix-command 'bmkp-here-menu)
+  (setcdr bmkp-here-menu bmkp-bookmarks-here-menu-command-entries))
+
+;; Add commands to other keymaps: Buffer-menu, Dired, EWW, Gnus, Info, Man, Woman, W3M.
+
+(add-hook (if (boundp 'Buffer-menu-mode-hook) 'Buffer-menu-mode-hook 'buffer-menu-mode-hook)
+          (lambda ()
+            (unless (lookup-key Buffer-menu-mode-map "j")
+              (define-key Buffer-menu-mode-map "j" 'bmkp-non-file-jump)) ; `j'
+            (define-key Buffer-menu-mode-map [menu-bar Buffer-menu-mode here]
+              `(menu-item "Bookmarks Here" bmkp-here-menu
+                          :enable (and bmkp-add-bookmarks-here-menu-flag
+                                       (bmkp-exists-this-file/buffer-bookmarks-p))))))
+
+(add-hook 'dired-mode-hook
+          (lambda ()
+            (let ((now  (lookup-key dired-mode-map "J")))
+              ;; Uppercase, since `j' is `dired-goto-file'.
+              (unless (and now  (not (eq now 'undefined))) ; `dired+.el' uses `undefined'.
+                (define-key dired-mode-map "J" 'bmkp-dired-jump)) ; `j'
+              (setq now  (lookup-key dired-mode-map "\C-j"))
+              (unless (and now  (not (eq now 'undefined))) ; `dired+.el' uses `undefined'.
+                (define-key dired-mode-map "\C-j" 'bmkp-dired-this-dir-jump))) ; `C-j'
+            (let ((map   dired-mode-map)
+                  (sep   '(menu-bar subdir separator-bmkp))
+                  (bdj   '(menu-bar subdir bmkp-dired-jump))
+                  (bdjc  '(menu-bar subdir bmkp-dired-this-dir-jump)))
+              (cond ((boundp 'diredp-bookmark-menu) ; In `dired+el'.
+                     (setq map   diredp-bookmark-menu
+                           sep   (cddr sep)
+                           bdj   (cddr bdj)
+                           bdjc  (cddr bdjc))
+                     (define-key map (apply #'vector bdjc)
+                       '(menu-item "Jump to a Dired Bookmark For This Dir" bmkp-dired-this-dir-jump
+                         :help "Jump to a bookmarked Dired buffer for this directory"))
+                     (define-key map (apply #'vector bdj)
+                       '(menu-item "Jump to a Dired Bookmark" bmkp-dired-jump
+                                   :help "Jump to a bookmarked Dired buffer"))
+                     (define-key map [bookmarks-here]
+                       `(menu-item "Here" bmkp-here-menu
+                                   :enable (and bmkp-add-bookmarks-here-menu-flag
+                                                (bmkp-exists-this-file/buffer-bookmarks-p)))))
+                    (t
+                     (define-key map (apply #'vector sep) '("--")) ;------------------------
+                     (define-key map (apply #'vector bdjc)
+                       '(menu-item "Jump to a Dired Bookmark For This Dir" bmkp-dired-this-dir-jump
+                         :help "Jump to a bookmarked Dired buffer for this directory"))
+                     (define-key map (apply #'vector bdj)
+                       '(menu-item "Jump to a Dired Bookmark" bmkp-dired-jump
+                                   :help "Jump to a bookmarked Dired buffer"))
+                     (define-key map [bookmarks-here]
+                       `(menu-item "Here" bmkp-here-menu
+                                   :enable (and bmkp-add-bookmarks-here-menu-flag
+                                                (bmkp-exists-this-file/buffer-bookmarks-p)))))))))
+
+(when (fboundp 'bmkp-eww-jump)          ; Emacs 24.4+
+  (add-hook 'eww-mode-hook
+            (lambda () (unless (lookup-key eww-mode-map "j")
+                    (define-key eww-mode-map "j" 'bmkp-eww-jump)))))
+
+(add-hook 'gnus-summary-mode-hook
+          (lambda () (unless (lookup-key gnus-summary-mode-map "j")
+                       (define-key gnus-summary-mode-map "j" 'bmkp-gnus-jump))))
+
+(add-hook 'Info-mode-hook
+          (lambda ()
+            (unless (lookup-key Info-mode-map "j")
+              (define-key Info-mode-map "j" 'bmkp-info-jump))
+            (define-key-after Info-mode-menu [bmkp-info-jump]
+              '(menu-item "Jump to an Info Bookmark" bmkp-info-jump
+                          :help "Jump to a bookmarked Info node")
+              'Go\ to\ Node\.\.\.) ; Used by `info(+).el' - corresponds to `Info-goto-node'.
+            (define-key Info-mode-menu [bookmarks-here]
+              `(menu-item "Bookmarks Here" bmkp-here-menu
+                          :enable (and bmkp-add-bookmarks-here-menu-flag
+                                       (bmkp-exists-this-file/buffer-bookmarks-p))))))
+
+(add-hook 'Man-mode-hook
+          (lambda () (unless (lookup-key Man-mode-map "j")
+                       (define-key Man-mode-map "j" 'bmkp-man-jump))))
+
+(add-hook 'woman-mode-hook
+          (lambda ()
+            (unless (lookup-key woman-mode-map "j") (define-key woman-mode-map "j" 'bmkp-man-jump))
+            (when (boundp 'woman-menu)
+              (define-key-after woman-menu [bmkp-man-jump]
+                '(menu-item "Jump to a `man'-page Bookmark" bmkp-man-jump
+                  :help "Jump to a bookmarked `man' page")
+                'WoMan\.\.\.))))        ; Used by `woman.el' - corresponds to command `woman'.
+
+(add-hook 'w3m-minor-mode-hook
+          (lambda () (unless (lookup-key w3m-minor-mode-map "j")
+                       (define-key w3m-minor-mode-map "j" 'bmkp-w3m-jump))))
+
+(add-hook 'w3m-mode-hook
+          (lambda () (unless (lookup-key w3m-mode-map "j")
+                       (define-key w3m-mode-map "j" 'bmkp-w3m-jump))))
+
+
+;;; Vanilla Emacs `Bookmarks' menu (see also [jump] from `Bookmark+' menu, below).
+
+(define-key-after menu-bar-bookmark-map [separator-edit] '("--") ;-------------------------------------
+                  'jump)
+;; Remove this predefined item - we use `bmkp-edit-bookmark-name-and-location' instead.
+(define-key menu-bar-bookmark-map [rename] nil)
+
+(define-key-after menu-bar-bookmark-map [bmkp-clone-bookmark]
+  '(menu-item "Clone (Duplicate) a Bookmark" bmkp-clone-bookmark
+    :help "Clone this bookmark.  (`\\[bmkp-edit-bookmark-record]' to edit.)")
+  'separator-edit)
+(define-key-after menu-bar-bookmark-map [bmkp-edit-bookmark-name-and-location]
+  '(menu-item "Rename or Relocate Bookmark..." bmkp-edit-bookmark-name-and-location
+    :help "Rename and/or relocate a bookmark")
+  'bmkp-clone-bookmark)
+(define-key-after menu-bar-bookmark-map [bmkp-edit-bookmark-record]
+  '(menu-item "Edit Bookmark Record (Lisp)..." bmkp-edit-bookmark-record
+    :help "Edit the internal record of a bookmark,a Lisp sexp")
+  'bmkp-edit-bookmark-name-and-location)
+
+(define-key-after menu-bar-bookmark-map [separator-show] '("--") ;-------------------------------------
+                  'bmkp-edit-bookmark-record)
+(define-key-after menu-bar-bookmark-map [edit]
+  '(menu-item "Show Bookmark List" bookmark-bmenu-list
+    :help "Open the list of bookmarks in buffer `*Bookmark List*'")
+  'separator-show)
+(define-key-after menu-bar-bookmark-map [bmkp-this-file/buffer-bmenu-list]
+  '(menu-item "Show Bookmark List for This File/Buffer" bmkp-this-file/buffer-bmenu-list
+    :help "Open `*Bookmark List*' for the bookmarks in the current buffer (only)")
+  'edit)
+(define-key-after menu-bar-bookmark-map [bmkp-navlist-bmenu-list]
+  '(menu-item "Show Bookmark List for Navlist" bmkp-navlist-bmenu-list
+    :help "Open `*Bookmark List*' for bookmarks in navlist (only)")
+  'bmkp-this-file/buffer-bmenu-list)
+
+(define-key-after menu-bar-bookmark-map [separator-2] '("--") ;-------------------------------------
+                  'bmkp-navlist-bmenu-list)
+(define-key-after menu-bar-bookmark-map [bmkp-choose-navlist-of-type]
+  '(menu-item "Set Navlist to Bookmarks of Type..." bmkp-choose-navlist-of-type
+    :help "Set the navigation list to the bookmarks of a certain type")
+  'separator-2)
+(define-key-after menu-bar-bookmark-map [bmkp-choose-navlist-from-bookmark-list]
+  '(menu-item "Set Navlist from Bookmark-List Bookmark..." bmkp-choose-navlist-from-bookmark-list
+    :help "Set the navigation list from a bookmark-list bookmark")
+  'bmkp-choose-navlist-of-type)
+(define-key-after menu-bar-bookmark-map [bmkp-list-defuns-in-commands-file]
+  '(menu-item "List User-Defined Bookmark Commands" bmkp-list-defuns-in-commands-file
+    :help "List the functions defined in `bmkp-bmenu-commands-file'"
+    :enable (and bmkp-bmenu-commands-file  (file-readable-p bmkp-bmenu-commands-file)))
+  'bmkp-choose-navlist-from-bookmark-list)
+
+(define-key-after menu-bar-bookmark-map [insert]
+  '(menu-item "Insert Bookmark Contents..." bookmark-insert :help "Insert bookmarked text")
+  'bmkp-choose-navlist-from-bookmark-list)
+(define-key-after menu-bar-bookmark-map [locate]
+  '(menu-item "Insert Bookmark Location..." bookmark-locate ; Alias for `bookmark-insert-location'.
+    :help "Insert a bookmark's file or buffer name")
+  'insert)
+(when (fboundp 'advice-add)             ; Emacs 24.4+.
+  (define-key-after menu-bar-bookmark-map [bmkp-store-org-link]
+    '(menu-item "Store Org Link To..." bmkp-store-org-link
+      :help "Store a link to a bookmark for insertion in an Org-mode buffer")
+    'locate))
+
+(define-key-after menu-bar-bookmark-map [separator-3] '("--") ;-------------------------------------
+                  (if (fboundp 'advice-add) 'bmkp-store-org-link 'locate))
+(define-key-after menu-bar-bookmark-map [save]
+  '(menu-item "Save Bookmarks" bookmark-save :help "Save currently defined bookmarks")
+  'separator-3)
+(define-key-after menu-bar-bookmark-map [write]
+  '(menu-item "Save Bookmarks As..." bookmark-write
+    :help "Write current bookmarks to a bookmark file")
+  'save)
+(define-key-after menu-bar-bookmark-map [bmkp-switch-bookmark-file-create]
+  '(menu-item "Switch to Bookmark File..." bmkp-switch-bookmark-file-create
+    :help "Switch to a different bookmark file, *replacing* the current set of bookmarks")
+  'write)
+(define-key-after menu-bar-bookmark-map [load]
+  '(menu-item "Add Bookmarks from File..." bookmark-load
+    :help "Load additional bookmarks from a bookmark file")
+  'bmkp-switch-bookmark-file-create)
+(define-key-after menu-bar-bookmark-map [bmkp-empty-file]
+  '(menu-item "Empty Bookmark File..." bmkp-empty-file
+    :help "Empty an existing bookmark file or create a new, empty bookmark file")
+  'load)
+
+
+;; `bmkp-annotate-menu' of vanilla `Bookmarks' menu: `Annotate'
+
+(defvar bmkp-annotate-menu (make-sparse-keymap)
+  "`Annotate' submenu for menu-bar `Bookmarks' menu.")
+(define-key menu-bar-bookmark-map [annotate] (cons "Annotate" bmkp-annotate-menu))
+
+(define-key bmkp-annotate-menu [bookmark-show-all-annotations]
+  '(menu-item "Show All Annotations" bookmark-show-all-annotations
+              :help "Show the annotations for all bookmarks"))
+(define-key bmkp-annotate-menu [bookmark-show-annotation]
+  '(menu-item "Show an Annotation" bookmark-show-annotation
+              :help "Show the annotation for a bookmark, or follow it if external"))
+(define-key bmkp-annotate-menu [bmkp-annotate-all-bookmarks-this-file/buffer]
+  '(menu-item "Annotate All Bookmarks Here" bmkp-annotate-all-bookmarks-this-file/buffer
+              :help "Pop up an annotation-editing buffer for each bookmark in this buffer"))
+(define-key bmkp-annotate-menu [bmkp-annotate-bookmark-this-file/buffer]
+  '(menu-item "Annotate a Bookmark Here" bmkp-annotate-bookmark-this-file/buffer
+              :help "Annotate an existing bookmark in this buffer"))
+(define-key bmkp-annotate-menu [bmkp-annotate-bookmark]
+  '(menu-item "Annotate a Bookmark" bmkp-annotate-bookmark
+              :help "Pop up a buffer to add or edit an annotation for a bookmark"))
+
+
+;; `bmkp-highlight-menu' of vanilla `Bookmarks' menu: `Highlight'
+
+(when (or (featurep 'bookmark+-lit)
+          (and (fboundp 'diredp-highlight-autofiles-mode)  (featurep 'highlight)))
+  (defvar bmkp-highlight-menu (make-sparse-keymap)
+    "`Highlight' submenu for menu-bar `Bookmarks' menu.")
+  (define-key menu-bar-bookmark-map [highlight] (cons "Highlight" bmkp-highlight-menu))
+
+  (when (featurep 'bookmark+-lit)
+    (define-key bmkp-highlight-menu [bmkp-unlight-bookmarks]
+      '(menu-item "Unhighlight All" bmkp-unlight-bookmarks
+                  :help "Unhighlight all bookmarks (everywhere)"))
+    (define-key bmkp-highlight-menu [bmkp-unlight-this-buffer]
+      '(menu-item "Unhighlight All in Buffer" bmkp-unlight-this-buffer
+                  :help "Unhighlight all bookmarks in this buffer"))
+    (define-key bmkp-highlight-menu [bmkp-unlight-non-autonamed-this-buffer]
+      '(menu-item "Unhighlight All Non-Autonamed in Buffer" bmkp-unlight-non-autonamed-this-buffer
+                  :help "Unhighlight all non-autonamed bookmarks in this buffer"))
+    (define-key bmkp-highlight-menu [bmkp-unlight-autonamed-this-buffer]
+      '(menu-item "Unhighlight All Autonamed in Buffer" bmkp-unlight-autonamed-this-buffer
+                  :help "Unhighlight all autonamed bookmarks in this buffer"))
+    (define-key bmkp-highlight-menu [bmkp-unlight-bookmark]
+      '(menu-item "Unhighlight One..." bmkp-unlight-bookmark
+                  :help "Unhighlight a bookmark"))
+    (define-key bmkp-highlight-menu [bmkp-unlight-bookmark-this-buffer]
+      '(menu-item "Unhighlight One in Buffer..." bmkp-unlight-bookmark-this-buffer
+                  :help "Unhighlight a bookmark in this buffer"))
+    (define-key bmkp-highlight-menu [bmkp-unlight-bookmark-here]
+      '(menu-item "Unhighlight This One" bmkp-unlight-bookmark-here
+                  :help "Unhighlight a bookmark at point or on its line"))
+
+    (define-key bmkp-highlight-menu [separator-2] '("--")) ;------------------------------------------
+    (define-key bmkp-highlight-menu [bmkp-light-bookmarks-in-region]
+      '(menu-item "Highlight All in Region" bmkp-light-bookmarks-in-region
+                  :help "Highlight all bookmarks in the region"))
+    (define-key bmkp-highlight-menu [bmkp-light-this-buffer]
+      '(menu-item "Highlight All in Buffer" bmkp-light-this-buffer
+                  :help "Highlight all bookmarks in this buffer"))
+    (define-key bmkp-highlight-menu [bmkp-light-non-autonamed-this-buffer]
+      '(menu-item "Highlight All Non-Autonamed in Buffer" bmkp-light-non-autonamed-this-buffer
+                  :help "Highlight all non-autonamed bookmarks in this buffer"))
+    (define-key bmkp-highlight-menu [bmkp-light-autonamed-this-buffer]
+      '(menu-item "Highlight All Autonamed in Buffer" bmkp-light-autonamed-this-buffer
+                  :help "Highlight all autonamed bookmarks in this buffer"))
+    (define-key bmkp-highlight-menu [bmkp-light-navlist-bookmarks]
+      '(menu-item "Highlight All in Navigation List" bmkp-light-navlist-bookmarks
+                  :help "Highlight all bookmarks in the navigation list"))
+    (define-key bmkp-highlight-menu [bmkp-light-bookmark-this-buffer]
+      '(menu-item "Highlight One in Buffer..." bmkp-light-bookmark-this-buffer
+                  :help "Highlight a bookmark in this buffer"))
+    (define-key bmkp-highlight-menu [bmkp-light-bookmark]
+      '(menu-item "Highlight One..." bmkp-light-bookmark
+                  :help "Highlight a bookmark"))
+
+    (define-key bmkp-highlight-menu [separator-1] '("--")) ;------------------------------------------
+    (define-key bmkp-highlight-menu [bmkp-describe-bookmark-lighted-here]
+      '(menu-item "Describe Highlighted Here (`C-u': internal form)"
+                  bmkp-describe-bookmark-lighted-here
+                  :help "Describe a highlighted bookmark on this line."
+                  :enable (and (fboundp 'bmkp-describe-bookmark-lighted-here)
+                               (or (bmkp-a-bookmark-lighted-at-pos (point) 'FULL)
+                                   (bmkp-a-bookmark-lighted-on-this-line 'FULL)))))
+    (define-key bmkp-highlight-menu [bmkp-bookmarks-lighted-at-point]
+      '(menu-item "List Highlighted at Point" bmkp-bookmarks-lighted-at-point
+                  :help "List the bookmarks at point that are highlighted"
+                  :enable (bmkp-bookmarks-lighted-at-point)))
+    (define-key bmkp-highlight-menu [bmkp-next-lighted-this-buffer]
+      '(menu-item "Next in Buffer" bmkp-next-lighted-this-buffer
+                  :help "Cycle to the next highlighted bookmark in this buffer"))
+    (define-key bmkp-highlight-menu [bmkp-previous-lighted-this-buffer]
+      '(menu-item "Previous in Buffer" bmkp-previous-lighted-this-buffer
+                  :help "Cycle to the previous highlighted bookmark in this buffer"))
+    (define-key bmkp-highlight-menu [separator-0] '("--")) ;------------------------------------------
+    )
+
+  (define-key bmkp-highlight-menu [diredp-highlight-autofiles-mode]
+    (bmkp-menu-bar-make-toggle diredp-highlight-autofiles-mode
+                               diredp-highlight-autofiles-mode
+                               "Toggle Autofile Highlighting in Dired"
+                               "Whether to highlight autofile bookmarks in Dired us biw %s"
+                               "Toggle `diredp-highlight-autofiles-mode'"
+                               nil
+                               :visible (and (fboundp 'diredp-highlight-autofiles-mode)
+                                             (featurep 'highlight))))
+
+  (when (featurep 'bookmark+-lit)
+    (define-key bmkp-highlight-menu [bmkp-set-lighting-for-bookmark]
+      '(menu-item "Set Highlighting for One..." bmkp-set-lighting-for-bookmark
+                  :help "Set individual highlighting for a bookmark"))))
+
+
+;; `bmkp-here-menu' of vanilla `Bookmarks' menu: `Here'
+
+(define-key menu-bar-bookmark-map [bookmarks-here]
+  `(menu-item "Here (This File/Buffer)" bmkp-here-menu
+              :enable (and bmkp-add-bookmarks-here-menu-flag
+                           (bmkp-exists-this-file/buffer-bookmarks-p))))
+
+
+;; `bmkp-delete-menu' of vanilla `Bookmarks' menu: `Delete'
+
+(defvar bmkp-delete-menu (make-sparse-keymap)
+  "`Delete' submenu for menu-bar `Bookmarks' menu.")
+(define-key menu-bar-bookmark-map [delete-menu] (cons "Delete" bmkp-delete-menu))
+
+(define-key bmkp-delete-menu [bmkp-delete-all-temporary-bookmarks]
+  '(menu-item "Delete All Temporaries..." bmkp-delete-all-temporary-bookmarks
+    :help "Delete the temporary bookmarks, (`X') whether visible here or not"))
+
+;;; $$$$$$ NOTE: Here and below, the definitions with logically correct `:enable' filters are
+;;;              commented out.  This is because evaluation of these filters is too slow, especially
+;;;              in older Emacs versions.  If you want to try some or all of the definitions with the
+;;;              `:enable' conditions, just uncomment them and comment out or remove the corresponding
+;;;              definitions without such conditions.
+
+;;;;; (define-key bmkp-delete-menu [bmkp-delete-all-autonamed-for-this-buffer]
+;;;;;   '(menu-item "Delete All Autonamed Bookmarks Here..."
+;;;;;     bmkp-delete-all-autonamed-for-this-buffer
+;;;;;     :help "Delete all autonamed bookmarks for the current buffer"
+;;;;;     :enable (mapcar #'bmkp-bookmark-name-from-record (bmkp-autonamed-this-buffer-alist-only))))
+(define-key bmkp-delete-menu [bmkp-delete-all-autonamed-for-this-buffer]
+  '(menu-item "Delete All Autonamed Bookmarks Here..."
+    bmkp-delete-all-autonamed-for-this-buffer
+    :help "Delete all autonamed bookmarks for the current buffer"))
+(define-key bmkp-delete-menu [bmkp-toggle-autoname-bookmark-delete]
+  '(menu-item "Delete Autonamed Bookmark" bmkp-toggle-autonamed-bookmark-set/delete
+    :help "Delete the autonamed bookmark at point"
+    :visible (bmkp-get-bookmark-in-alist (funcall bmkp-autoname-bookmark-function (point))
+              'noerror)))
+;;;;; (define-key bmkp-delete-menu [bmkp-delete-bookmarks]
+;;;;;   '(menu-item "Delete Bookmarks Here..." bmkp-delete-bookmarks
+;;;;;     :help "Delete some bookmarks at point or, with `C-u', all bookmarks in the buffer"
+;;;;;     :enable (mapcar #'bmkp-bookmark-name-from-record (bmkp-this-buffer-alist-only))))
+(define-key bmkp-delete-menu [bmkp-delete-bookmarks]
+  '(menu-item "Delete Bookmarks Here..." bmkp-delete-bookmarks
+    :help "Delete some bookmarks at point or, with `C-u', all bookmarks in the buffer"))
+(define-key bmkp-delete-menu [delete]
+  '(menu-item "Delete Bookmark..." bookmark-delete :help "Delete the bookmark you choose by name"))
+(define-key bmkp-delete-menu [bmkp-purge-notags-autofiles]
+  '(menu-item "Purge Autofiles with No Tags..." bmkp-purge-notags-autofiles
+    :help "Delete all autofile bookmarks that have no tags"))
+
+;; Remove vanilla `bookmark-delete' entry from main `Bookmarks' menu.
+(define-key menu-bar-bookmark-map [delete] nil)
+
+
+;; `bmkp-set-bookmark-menu' of vanilla `Bookmarks' menu: `New/Update'
+(defvar bmkp-set-bookmark-menu (make-sparse-keymap)
+  "`New/Update' submenu for menu-bar `Bookmarks' menu.")
+(define-key menu-bar-bookmark-map [set-bookmark] (cons "New/Update" bmkp-set-bookmark-menu))
+
+(defun bmkp-menu-bar-set-bookmark ()
+  "Set a bookmark, prompting for the name."
+  (interactive)
+  (call-interactively #'bmkp-bookmark-set-confirm-overwrite))
+  
+(define-key bmkp-set-bookmark-menu [bmkp-make-function-bookmark]
+  '(menu-item "Function Bookmark..." bmkp-make-function-bookmark
+    :help "Create a bookmark that will invoke a function when \"jumped\" to"))
+(define-key bmkp-set-bookmark-menu [bmkp-toggle-autoname-bookmark-set]
+  '(menu-item "Autonamed Bookmark" bmkp-toggle-autonamed-bookmark-set/delete
+    :help "Set an autonamed bookmark at point"
+    :visible (not (bmkp-get-bookmark-in-alist (funcall bmkp-autoname-bookmark-function (point))
+                                              'NOERROR))))
+(define-key bmkp-set-bookmark-menu [bmkp-set-bookmark-file-bookmark]
+  '(menu-item "Bookmark-File Bookmark..." bmkp-set-bookmark-file-bookmark
+    :help "Set a bookmark that loads a bookmark file when jumped to"))
+(define-key bmkp-set-bookmark-menu [bmkp-set-desktop-bookmark]
+  '(menu-item "Desktop Bookmark" bmkp-set-desktop-bookmark
+    :help "Save the current desktop as a bookmark"))
+(define-key bmkp-set-bookmark-menu [bmkp-url-target-set]
+  '(menu-item "URL Bookmark..." bmkp-url-target-set
+    :help "Set a bookmark for a given URL"))
+(define-key bmkp-set-bookmark-menu [bmkp-file-target-set]
+  '(menu-item "File Bookmark..." bmkp-file-target-set
+    :help "Set a bookmark with a given name for a given file"))
+(define-key bmkp-set-bookmark-menu [bmkp-autofile-set]
+  '(menu-item "Autofile Bookmark..." bmkp-autofile-set
+    :help "Set and automatically name a bookmark for a given file"))
+(define-key bmkp-set-bookmark-menu [bmkp-menu-bar-set-bookmark]
+  '(menu-item "Ordinary Bookmark..." bmkp-menu-bar-set-bookmark
+    :help "Set a bookmark at point" :keys "(C-x x m)")) ; Really bound to `bookmark-set'
+
+
+;; Remove vanilla `bookmark-set' from main `Bookmarks' menu.
+(define-key menu-bar-bookmark-map [set] nil)
+
+
+;; `bmkp-options-menu' of vanilla `Bookmarks' menu: `Toggle'.  Reuse `bmkp-bmenu-toggle-menu'.
+(define-key menu-bar-bookmark-map [options] (cons "Toggle" bmkp-bmenu-toggle-menu))
+
+
+;; `bmkp-tags-menu' of vanilla `Bookmarks' menu: `Tags'
+
+(defvar bmkp-tags-menu (make-sparse-keymap)
+  "`Tags' submenu for menu-bar `Bookmarks' menu.")
+(define-key menu-bar-bookmark-map [tags] (cons "Tags" bmkp-tags-menu))
+
+(define-key bmkp-tags-menu [bmkp-list-all-tags]
+  '(menu-item "List All Tags" bmkp-list-all-tags :help "List all tags used for any bookmarks"))
+(define-key bmkp-tags-menu [bmkp-purge-notags-autofiles]
+  '(menu-item "Purge Autofiles with No Tags..." bmkp-purge-notags-autofiles
+    :help "Delete all autofile bookmarks that have no tags"))
+(define-key bmkp-tags-menu [bmkp-untag-a-file]
+  '(menu-item "Untag a File (Remove Some)..." bmkp-untag-a-file
+    :help "Remove some tags from autofile bookmark for a file"))
+(define-key bmkp-tags-menu [bmkp-tag-a-file]
+  '(menu-item "Tag a File (Add Some)..." bmkp-tag-a-file
+    :help "Add some tags to the autofile bookmark for a file"))
+
+(define-key bmkp-tags-menu [tags-sep1] '("--")) ;----------------------------------------------
+(define-key bmkp-tags-menu [bmkp-rename-tag]
+  '(menu-item "Rename Tag..." bmkp-rename-tag :help "Rename a tag in all bookmarks"))
+(define-key bmkp-tags-menu [bmkp-set-tag-value]
+  '(menu-item "Set Tag Value..." bmkp-set-tag-value :help "Set the tag value for a given bookmark"))
+(define-key bmkp-tags-menu [bmkp-remove-tags-from-all]
+  '(menu-item "Remove Some Tags from All..." bmkp-remove-tags-from-all
+    :help "Remove a set of tags from all bookmarks"))
+(define-key bmkp-tags-menu [bmkp-remove-tags]
+  '(menu-item "Remove Some Tags..." bmkp-remove-tags :help "Remove a set of tags from a bookmark"))
+(define-key bmkp-tags-menu [bmkp-add-tags]
+  '(menu-item "Add Some Tags..." bmkp-add-tags :help "Add a set of tags to a bookmark"))
+(define-key bmkp-tags-menu [bmkp-paste-replace-tags]
+  '(menu-item "Paste Tags (Replace)..." bmkp-paste-replace-tags
+    :help "Replace tags for a bookmark with tags copied from another"))
+(define-key bmkp-tags-menu [bmkp-paste-add-tags]
+  '(menu-item "Paste Tags (Add)..." bmkp-paste-add-tags
+    :help "Add tags to a bookmark that were previously copied from another"))
+(define-key bmkp-tags-menu [bmkp-copy-tags]
+  '(menu-item "Copy Tags..." bmkp-copy-tags
+    :help "Copy the tags from a bookmark, so you can paste them to another"))
+(define-key bmkp-tags-menu [bmkp-edit-tags]
+  '(menu-item "Edit Tags..." bmkp-edit-tags :help "Edit the tags of a bookmark"))
+
+
+;; `bmkp-jump-menu' of vanilla `Bookmarks' menu: `Jump To'
+
+(defvar bmkp-jump-menu (make-sparse-keymap)
+  "`Jump To' submenu for menu-bar `Bookmarks' menu.")
+;; Add jump menu to vanilla Emacs `Bookmarks' menu and remove the two jump commands already there.
+(define-key menu-bar-bookmark-map [jump] nil)
+(define-key menu-bar-bookmark-map [jump-other] nil)
+(define-key menu-bar-bookmark-map [bmkp-jump] (cons "Jump To" bmkp-jump-menu))
+
+;; `Jump To': Add jump menu also to the `Bookmark+' menu, and remove the two jump commands there.
+(define-key bmkp-bmenu-menubar-menu [jump] (cons "Jump To" bmkp-jump-menu))
+
+(define-key bmkp-jump-menu [bmkp-temporary-jump-other-window]
+  '(menu-item "Temporary..." bmkp-temporary-jump-other-window
+    :help "Jump to a temporary bookmark"))
+(define-key bmkp-jump-menu [bmkp-autofile-jump-other-window]
+  '(menu-item "Autofile..." bmkp-autofile-jump-other-window
+    :help "Jump to an autofile bookmark"))
+(define-key bmkp-jump-menu [bmkp-autonamed-this-buffer-jump]
+  '(menu-item "Autonamed for This Buffer..." bmkp-autonamed-this-buffer-jump
+    :help "Jump to an autonamed bookmark in this buffer"))
+(define-key bmkp-jump-menu [bmkp-autonamed-jump-other-window]
+  '(menu-item "Autonamed..." bmkp-autonamed-jump-other-window
+    :help "Jump to an autonamed bookmark"))
+(define-key bmkp-jump-menu [bmkp-specific-files-jump-other-window]
+  '(menu-item "For Specific Files..." bmkp-specific-files-jump-other-window
+    :help "Jump to a bookmark for specific files"))
+(define-key bmkp-jump-menu [bmkp-specific-buffers-jump-other-window]
+  '(menu-item "For Specific Buffers..." bmkp-specific-buffers-jump-other-window
+    :help "Jump to a bookmark for specific buffers"))
+;;;;; (define-key bmkp-jump-menu [bmkp-this-buffer-jump]
+;;;;;   '(menu-item "For This Buffer..." bmkp-this-buffer-jump
+;;;;;     :help "Jump to a bookmark for the current buffer"
+;;;;;     :enable (mapcar #'bmkp-bookmark-name-from-record (bmkp-this-buffer-alist-only))))
+(define-key bmkp-jump-menu [bmkp-this-buffer-jump]
+  '(menu-item "For This Buffer..." bmkp-this-buffer-jump
+    :help "Jump to a bookmark for the current buffer"))
+;;;;; (when (featurep 'bookmark+-lit)
+;;;;;   (define-key bmkp-jump-menu [bmkp-lighted-jump-other-window]
+;;;;;     '(menu-item "Highlighted..." bmkp-lighted-jump-other-window
+;;;;;       :help "Jump to a highlighted bookmark"
+;;;;;       :enable (bmkp-lighted-alist-only))))
+(when (featurep 'bookmark+-lit)
+  (define-key bmkp-jump-menu [bmkp-lighted-jump-other-window]
+    '(menu-item "Highlighted..." bmkp-lighted-jump-other-window
+      :help "Jump to a highlighted bookmark")))
+(define-key bmkp-jump-menu [bmkp-jump-in-navlist-other-window]
+  '(menu-item "In Navigation List..." bmkp-jump-in-navlist-other-window
+    :help "Jump to a bookmark that is in the navigation list" :enable bmkp-nav-alist))
+
+(define-key bmkp-jump-menu [jump-sep0] '("--")) ;---------------------------------------------------
+;;;;; (define-key bmkp-jump-menu [bmkp-url-jump-other-window]
+;;;;;   '(menu-item "URL..." bmkp-url-jump-other-window :help "Jump to a URL bookmark"
+;;;;;     :enable (bmkp-url-alist-only)))
+(define-key bmkp-jump-menu [bmkp-url-jump-other-window]
+  '(menu-item "URL..." bmkp-url-jump-other-window :help "Jump to a URL bookmark"))
+;;;;; (define-key bmkp-jump-menu [bmkp-gnus-jump-other-window]
+;;;;;   '(menu-item "Gnus..." bmkp-gnus-jump-other-window :help "Jump to a Gnus bookmark"
+;;;;;     :enable (bmkp-gnus-alist-only)))
+(define-key bmkp-jump-menu [bmkp-gnus-jump-other-window]
+  '(menu-item "Gnus..." bmkp-gnus-jump-other-window :help "Jump to a Gnus bookmark"))
+;;;;; (define-key bmkp-jump-menu [bmkp-man-jump-other-window]
+;;;;;   '(menu-item "Man Page..." bmkp-man-jump-other-window :help "Jump to a `man'-page bookmark"
+;;;;;     :enable (bmkp-man-alist-only)))
+(define-key bmkp-jump-menu [bmkp-man-jump-other-window]
+  '(menu-item "Man Page..." bmkp-man-jump-other-window :help "Jump to a `man'-page bookmark"))
+;;;;; (define-key bmkp-jump-menu [bmkp-info-jump-other-window]
+;;;;;   '(menu-item "Info Node..." bmkp-info-jump-other-window :help "Jump to an Info bookmark"
+;;;;;     :enable (bmkp-info-alist-only)))
+(define-key bmkp-jump-menu [bmkp-info-jump-other-window]
+  '(menu-item "Info Node..." bmkp-info-jump-other-window :help "Jump to an Info bookmark"))
+;;;;; (define-key bmkp-jump-menu [bmkp-image-jump-other-window]
+;;;;;   '(menu-item "Image..." bmkp-image-jump-other-window :help "Jump to an image-file bookmark"
+;;;;;     :enable (bmkp-image-alist-only)))
+(define-key bmkp-jump-menu [bmkp-image-jump-other-window]
+  '(menu-item "Image..." bmkp-image-jump-other-window :help "Jump to an image-file bookmark"))
+;;;;; (define-key bmkp-jump-menu [bmkp-non-file-jump-other-window]
+;;;;;   '(menu-item "Buffer (Non-File)..." bmkp-non-file-jump-other-window
+;;;;;     :help "Jump to a non-file (buffer) bookmark" :enable (bmkp-non-file-alist-only)))
+(define-key bmkp-jump-menu [bmkp-non-file-jump-other-window]
+  '(menu-item "Buffer (Non-File)..." bmkp-non-file-jump-other-window
+    :help "Jump to a non-file (buffer) bookmark"))
+;;;;; (define-key bmkp-jump-menu [bmkp-region-jump-other-window]
+;;;;;   '(menu-item "Region..." bmkp-region-jump-other-window
+;;;;;     :help "Jump to a bookmark that defines the active region" :enable (bmkp-region-alist-only)))
+(define-key bmkp-jump-menu [bmkp-region-jump-other-window]
+  '(menu-item "Region..." bmkp-region-jump-other-window
+    :help "Jump to a bookmark that defines the active region"))
+;;;;; (define-key bmkp-jump-menu [bmkp-remote-file-jump-other-window]
+;;;;;   '(menu-item "Remote File..." bmkp-remote-file-jump-other-window
+;;;;;     :help "Jump to a remote file or directory bookmark" :enable (bmkp-remote-file-alist-only)))
+(define-key bmkp-jump-menu [bmkp-remote-file-jump-other-window]
+  '(menu-item "Remote File..." bmkp-remote-file-jump-other-window
+    :help "Jump to a remote file or directory bookmark"))
+;;;;; (define-key bmkp-jump-menu [bmkp-local-file-jump-other-window]
+;;;;;   '(menu-item "Local File..." bmkp-local-file-jump-other-window
+;;;;;     :help "Jump to a local file or directory bookmark" :enable (bmkp-local-file-alist-only)))
+(define-key bmkp-jump-menu [bmkp-local-file-jump-other-window]
+  '(menu-item "Local File..." bmkp-local-file-jump-other-window
+    :help "Jump to a local file or directory bookmark"))
+;;;;; (define-key bmkp-jump-menu [bmkp-file-this-dir-jump-other-window]
+;;;;;   '(menu-item "File in This Dir..." bmkp-file-this-dir-jump-other-window
+;;;;;     :help "Jump to a bookmark for a file or subdirectory in the `default-directory'."
+;;;;;     :enable (bmkp-file-alist-only)))
+(define-key bmkp-jump-menu [bmkp-file-this-dir-jump-other-window]
+  '(menu-item "File in This Dir..." bmkp-file-this-dir-jump-other-window
+    :help "Jump to a bookmark for a file or subdirectory in the `default-directory'."))
+;;;;; (define-key bmkp-jump-menu [bmkp-file-jump-other-window]
+;;;;;   '(menu-item "File..." bmkp-file-jump-other-window :help "Jump to a file or directory bookmark"
+;;;;;     :enable (bmkp-file-alist-only)))
+(define-key bmkp-jump-menu [bmkp-file-jump-other-window]
+  '(menu-item "File..." bmkp-file-jump-other-window :help "Jump to a file or directory bookmark"))
+;;;;; (define-key bmkp-jump-menu [bmkp-dired-this-dir-jump-other-window]
+;;;;;   '(menu-item "Dired for This Dir..." bmkp-dired-this-dir-jump-other-window
+;;;;;     :help "Jump to a Dired bookmark for `default-directory', restoring recorded state"
+;;;;;     :enable (bmkp-dired-alist-only)))
+(define-key bmkp-jump-menu [bmkp-dired-this-dir-jump-other-window]
+  '(menu-item "Dired for This Dir..." bmkp-dired-this-dir-jump-other-window
+    :help "Jump to a Dired bookmark for `default-directory', restoring recorded state"))
+;;;;; (define-key bmkp-jump-menu [bmkp-dired-jump-other-window]
+;;;;;   '(menu-item "Dired..." bmkp-dired-jump-other-window
+;;;;;     :help "Jump to a Dired bookmark, restoring the recorded Dired state"
+;;;;;     :enable (bmkp-dired-alist-only)))
+(define-key bmkp-jump-menu [bmkp-dired-jump-other-window]
+  '(menu-item "Dired..." bmkp-dired-jump-other-window
+    :help "Jump to a Dired bookmark, restoring the recorded Dired state"))
+;;;;; (define-key bmkp-jump-menu [bmkp-variable-list-jump]
+;;;;;   '(menu-item "Variable List..." bmkp-variable-list-jump :help "Jump to a variable-list bookmark"
+;;;;;     :enable (bmkp-variable-list-alist-only)))
+(define-key bmkp-jump-menu [bmkp-variable-list-jump]
+  '(menu-item "Variable List..." bmkp-variable-list-jump :help "Jump to a variable-list bookmark"))
+;;;;; (define-key bmkp-jump-menu [bmkp-bookmark-file-jump]
+;;;;;   '(menu-item "Bookmark File..." bmkp-bookmark-file-jump
+;;;;;     :help "Jump to (load) a bookmark-file bookmark" :enable (bmkp-bookmark-file-alist-only)))
+(define-key bmkp-jump-menu [bmkp-bookmark-file-jump]
+  '(menu-item "Bookmark File..." bmkp-bookmark-file-jump
+    :help "Jump to (load) a bookmark-file bookmark"))
+;;;;; (define-key bmkp-jump-menu [bmkp-bookmark-list-jump]
+;;;;;   '(menu-item "Bookmark List..." bmkp-bookmark-list-jump :help "Jump to a bookmark-list bookmark"
+;;;;;     :enable (bmkp-bookmark-list-alist-only)))
+(define-key bmkp-jump-menu [bmkp-bookmark-list-jump]
+  '(menu-item "Bookmark List..." bmkp-bookmark-list-jump :help "Jump to a bookmark-list bookmark"))
+;;;;; (define-key bmkp-jump-menu [bmkp-desktop-jump]
+;;;;;   '(menu-item "Desktop..." bmkp-desktop-jump :help "Jump to a desktop bookmark"
+;;;;;     :enable (bmkp-desktop-alist-only)))
+(define-key bmkp-jump-menu [bmkp-desktop-jump]
+  '(menu-item "Desktop..." bmkp-desktop-jump :help "Jump to a desktop bookmark"))
+(define-key bmkp-jump-menu [bmkp-jump-to-type-other-window]
+  '(menu-item "Of Type..." bmkp-jump-to-type-other-window
+    :help "Jump to a bookmark of a type that you specify"))
+
+(define-key bmkp-jump-menu [bookmark-jump-other-window]
+  '(menu-item "Any in Other Window..." bookmark-jump-other-window
+    :help "Jump to a bookmark of any type, in another window"))
+(define-key bmkp-jump-menu [bookmark-jump]
+  '(menu-item "Any..." bookmark-jump :help "Jump to a bookmark of any type, in this window"))
+
+(define-key bmkp-jump-menu [bmkp-bmenu-jump-to-marked]
+  '(menu-item "Marked" bmkp-bmenu-jump-to-marked
+    :help "Jump to each bookmark marked `>', in another window"
+    :enable (and bmkp-bmenu-marked-bookmarks  (equal (buffer-name (current-buffer))
+                                               bmkp-bmenu-buffer))))
+
+
+;; `bmkp-jump-tags-menu' of vanilla `Bookmarks' menu: `Jump To' > `With Tags'
+
+(defvar bmkp-jump-tags-menu (make-sparse-keymap)
+  "`With Tags' submenu for `Jump To' submenu of `Bookmarks' menu.")
+(define-key bmkp-jump-menu [bmkp-tags] (cons "With Tags" bmkp-jump-tags-menu))
+(define-key bmkp-jump-tags-menu [bmkp-file-this-dir-all-tags-regexp-jump-other-window]
+  '(menu-item "File in This Dir, All Tags Matching Regexp..."
+    bmkp-file-this-dir-all-tags-regexp-jump-other-window
+    :help "Jump to a file bookmark in this dir where each tag matches a regexp"))
+(define-key bmkp-jump-tags-menu [bmkp-file-this-dir-some-tags-regexp-jump-other-window]
+  '(menu-item "File in This Dir, Any Tag Matching Regexp..."
+    bmkp-file-this-dir-some-tags-regexp-jump-other-window
+    :help "Jump to a file bookmark in this dir where at least one tag matches a regexp"))
+(define-key bmkp-jump-tags-menu [bmkp-file-this-dir-all-tags-jump-other-window]
+  '(menu-item "File in This Dir, All Tags in Set..." bmkp-file-this-dir-all-tags-jump-other-window
+    :help "Jump to a file bookmark in this dir that has all of a set of tags that you enter"))
+(define-key bmkp-jump-tags-menu [bmkp-file-this-dir-some-tags-jump-other-window]
+  '(menu-item "File in This Dir, Any Tag in Set..." bmkp-file-this-dir-some-tags-jump-other-window
+    :help "Jump to a file bookmark in this dir that has some of a set of tags that you enter"))
+
+(define-key bmkp-jump-tags-menu [jump-sep5] '("--")) ;----------------------------------------------
+(define-key bmkp-jump-tags-menu [bmkp-file-all-tags-regexp-jump-other-window]
+  '(menu-item "File, All Tags Matching Regexp..." bmkp-file-all-tags-regexp-jump-other-window
+    :help "Jump to a file or dir bookmark where each tag matches a regexp that you enter"))
+(define-key bmkp-jump-tags-menu [bmkp-file-some-tags-regexp-jump-other-window]
+  '(menu-item "File, Any Tag Matching Regexp..." bmkp-file-some-tags-regexp-jump-other-window
+    :help "Jump to a file or dir bookmark where at least one tag matches a regexp that you enter"))
+(define-key bmkp-jump-tags-menu [bmkp-file-all-tags-jump-other-window]
+  '(menu-item "File, All Tags in Set..." bmkp-file-all-tags-jump-other-window
+    :help "Jump to a file or dir bookmark that has all of a set of tags that you enter"))
+(define-key bmkp-jump-tags-menu [bmkp-file-some-tags-jump-other-window]
+  '(menu-item "File, Any Tag in Set..." bmkp-file-some-tags-jump-other-window
+    :help "Jump to a file or dir bookmark that has some of a set of tags that you enter"))
+
+(define-key bmkp-jump-tags-menu [jump-sep4] '("--")) ;----------------------------------------------
+(define-key bmkp-jump-tags-menu [bmkp-autofile-all-tags-regexp-jump-other-window]
+  '(menu-item "Autofile, All Tags Matching Regexp..."
+    bmkp-autofile-all-tags-regexp-jump-other-window
+    :help "Jump to an autofile bookmark where each tag matches a regexp that you enter"))
+(define-key bmkp-jump-tags-menu [bmkp-autofile-some-tags-regexp-jump-other-window]
+  '(menu-item "Autofile, Any Tag Matching Regexp..."
+    bmkp-autofile-some-tags-regexp-jump-other-window
+    :help "Jump to an autofile bookmark where at least one tag matches a regexp that you enter"))
+(define-key bmkp-jump-tags-menu [bmkp-autofile-all-tags-jump-other-window]
+  '(menu-item "Autofile, All Tags in Set..."
+    bmkp-autofile-all-tags-jump-other-window
+    :help "Jump to an autofile bookmark that has all of a set of tags that you enter"))
+(define-key bmkp-jump-tags-menu [bmkp-autofile-some-tags-jump-other-window]
+  '(menu-item "Autofile, Any Tag in Set..." bmkp-autofile-some-tags-jump-other-window
+    :help "Jump to an autofile bookmark that has some of a set of tags that you enter"))
+
+(when (fboundp 'bmkp-find-file-all-tags) ; Emacs 21+
+  (define-key bmkp-jump-tags-menu [jump-sep3] '("--")) ;----------------------------------------------
+  (define-key bmkp-jump-tags-menu [bmkp-find-file-all-tags-regexp-other-window]
+    '(menu-item "Find Autofile, All Tags Matching Regexp..."
+      bmkp-find-file-all-tags-regexp-other-window
+      :help "Visit a bookmarked file where each tag matches a regexp that you enter"))
+  (define-key bmkp-jump-tags-menu [bmkp-find-file-some-tags-regexp-other-window]
+    '(menu-item "Find Autofile, Any Tag Matching Regexp..."
+      bmkp-find-file-some-tags-regexp-other-window
+      :help "Visit a bookmarked file where at least one tag matches a regexp that you enter"))
+  (define-key bmkp-jump-tags-menu [bmkp-find-file-all-tags-other-window]
+    '(menu-item "Find Autofile, All Tags in Set..."
+      bmkp-find-file-all-tags-other-window
+      :help "Visit a bookmarked file that has all of a set of tags that you enter"))
+  (define-key bmkp-jump-tags-menu [bmkp-find-file-some-tags-other-window]
+    '(menu-item "Find Autofile, Any Tag in Set..." bmkp-find-file-some-tags-other-window
+      :help "Visit a bookmarked file that has some of a set of tags that you enter")))
+
+(define-key bmkp-jump-tags-menu [jump-sep2] '("--")) ;----------------------------------------------
+(define-key bmkp-jump-tags-menu [bmkp-all-tags-regexp-jump-other-window]
+  '(menu-item "All Tags Matching Regexp..." bmkp-all-tags-regexp-jump-other-window
+    :help "Jump to a bookmark that has each tag matching a regexp that you enter"))
+(define-key bmkp-jump-tags-menu [bmkp-some-tags-regexp-jump-other-window]
+  '(menu-item "Any Tag Matching Regexp..." bmkp-some-tags-regexp-jump-other-window
+    :help "Jump to a bookmark that has at least one tag matching a regexp that you enter"))
+(define-key bmkp-jump-tags-menu [bmkp-all-tags-jump-other-window]
+  '(menu-item "All Tags in Set..." bmkp-all-tags-jump-other-window
+    :help "Jump to a bookmark that has all of a set of tags that you enter"))
+(define-key bmkp-jump-tags-menu [bmkp-some-tags-jump-other-window]
+  '(menu-item "Any Tag in Set..." bmkp-some-tags-jump-other-window
+    :help "Jump to a bookmark that has some of a set of tags that you enter"))
+
+
+;; `File' > `Find File or Autofile' submenu
+;; or, for Emacs 20-21, single item `File' > `Find File or Autofile...'.
+(if (not (fboundp 'bmkp-find-file-all-tags))
+    (define-key menu-bar-file-menu [bmkp-find-file-other-window] ; Emacs 20-21
+      '(menu-item "Find File or Autofile..." bmkp-find-file-other-window))
+  (defvar bmkp-find-file-menu (make-sparse-keymap)
+    "`Find File or Autofile' submenu for menu-bar `File' menu.")
+  (define-key menu-bar-file-menu [bmkp-find-file-menu]
+    (list 'menu-item "Find File or Autofile" bmkp-find-file-menu))
+  (define-key bmkp-find-file-menu [bmkp-find-file-all-tags-regexp-other-window]
+    '(menu-item "All Tags Matching Regexp..." bmkp-find-file-all-tags-regexp-other-window
+      :help "Visit a file or dir where each tag matches a regexp that you enter"))
+  (define-key bmkp-find-file-menu [bmkp-find-file-some-tags-regexp-other-window]
+    '(menu-item "Any Tag Matching Regexp..." bmkp-find-file-some-tags-regexp-other-window
+      :help "Jump to a file or dir bookmark where at least one tag matches a regexp that you enter"))
+  (define-key bmkp-find-file-menu [bmkp-find-file-all-tags-other-window]
+    '(menu-item "All Tags in Set..." bmkp-find-file-all-tags-other-window
+      :help "Visit a file or dir that has all of a set of tags that you enter"))
+  (define-key bmkp-find-file-menu [bmkp-find-file-some-tags-other-window]
+    '(menu-item "Any Tag in Set..." bmkp-find-file-some-tags-other-window
+      :help "Visit a file or dir that has some of a set of tags that you enter"))
+  (define-key bmkp-find-file-menu [find-file-sep2] '("--")) ;---------
+  (define-key bmkp-find-file-menu [bmkp-find-file-other-window]
+    '(menu-item "Any File or Autofile..." bmkp-find-file-other-window
+      :help "Visit a bookmarked file or directory: an autofile bookmark.")))
+
+;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'bookmark+-key)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; bookmark+-key.el ends here
diff --git a/lisp/bookmark+-lit.el b/lisp/bookmark+-lit.el
new file mode 100644 (file)
index 0000000..9149688
--- /dev/null
@@ -0,0 +1,1541 @@
+;;; bookmark+-lit.el --- Bookmark highlighting for Bookmark+.
+;;
+;; Filename: bookmark+-lit.el
+;; Description: Bookmark highlighting for Bookmark+.
+;; Author: Drew Adams
+;; Maintainer: Drew Adams
+;; Copyright (C) 2010-2022, Drew Adams, all rights reserved.
+;; Created: Wed Jun 23 07:49:32 2010 (-0700)
+;; Last-Updated: Fri Jan 14 12:50:59 2022 (-0800)
+;;           By: dradams
+;;     Update #: 1005
+;; URL: https://www.emacswiki.org/emacs/download/bookmark%2b-lit.el
+;; Doc URL: https://www.emacswiki.org/emacs/BookmarkPlus
+;; Keywords: bookmarks, highlighting, bookmark+
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x, 24.x, 25.x, 26.x
+;;
+;; Features that might be required by this library:
+;;
+;;   `bookmark', `pp', `pp+'.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;    Bookmark highlighting for Bookmark+ (library `bookmark+.el').
+;;
+;;    The Bookmark+ libraries are:
+;;
+;;    `bookmark+.el'     - main code library
+;;    `bookmark+-mac.el' - Lisp macros
+;;    `bookmark+-lit.el' - code for highlighting bookmarks (this file)
+;;    `bookmark+-bmu.el' - code for the `*Bookmark List*'
+;;    `bookmark+-1.el'   - other required code (non-bmenu)
+;;    `bookmark+-key.el' - key and menu bindings
+;;
+;;    `bookmark+-doc.el' - documentation (comment-only file)
+;;    `bookmark+-chg.el' - change log (comment-only file)
+;;
+;;    This library (`bookmark+-lit.el') is a Bookmark+ option.  If you
+;;    want to use it then load it before loading `bookmark+.el', so
+;;    that its commands can be bound to keys and menu items.
+;;
+;;    The documentation (in `bookmark+-doc.el') includes how to
+;;    byte-compile and install Bookmark+.  The documentation is also
+;;    available in these ways:
+;;
+;;    1. From the bookmark list (`C-x r l'):
+;;       Use `?' to show the current bookmark-list status and general
+;;       help, then click link `Doc in Commentary' or link `Doc on the
+;;       Web'.
+;;
+;;    2. From the Emacs-Wiki Web site:
+;;       https://www.emacswiki.org/emacs/BookmarkPlus.
+;;
+;;    3. From the Bookmark+ group customization buffer:
+;;       `M-x customize-group bookmark-plus', then click link
+;;       `Commentary'.
+;;
+;;    (The commentary links in #1 and #3 work only if you have library
+;;    `bookmark+-doc.el' in your `load-path'.)
+ 
+;;(@> "Index")
+;;
+;;  Index
+;;  -----
+;;
+;;  If you have library `linkd.el' and Emacs 22 or later, load
+;;  `linkd.el' and turn on `linkd-mode' now.  It lets you easily
+;;  navigate around the sections of this doc.  Linkd mode will
+;;  highlight this Index, as well as the cross-references and section
+;;  headings throughout this file.  You can get `linkd.el' here:
+;;  https://www.emacswiki.org/emacs/download/linkd.el.
+;;
+;;  (@> "Things Defined Here")
+;;  (@> "Faces (Customizable)")
+;;  (@> "User Options (Customizable)")
+;;  (@> "Internal Variables")
+;;  (@> "Functions")
+;;    (@> "Menu-List (`*-bmenu-*') Commands")
+;;    (@> "General Highlight Commands")
+;;    (@> "Other Functions")
+ 
+;;(@* "Things Defined Here")
+;;
+;;  Things Defined Here
+;;  -------------------
+;;
+;;  Commands defined here:
+;;
+;;
+;;    `bmkp-bmenu-light', `bmkp-bmenu-light-marked',
+;;    `bmkp-bmenu-set-lighting', `bmkp-bmenu-set-lighting-for-marked',
+;;    `bmkp-bmenu-show-only-lighted-bookmarks', `bmkp-bmenu-unlight',
+;;    `bmkp-bmenu-unlight-marked', `bmkp-bookmarks-lighted-at-point',
+;;    `bmkp-cycle-lighted-this-buffer',
+;;    `bmkp-cycle-lighted-this-buffer-other-window',
+;;    `bmkp-describe-bookmark-lighted-here',
+;;    `bmkp-light-autonamed-this-buffer', `bmkp-light-bookmark',
+;;    `bmkp-light-bookmark-this-buffer', `bmkp-light-bookmarks',
+;;    `bmkp-light-bookmarks-in-region',
+;;    `bmkp-light-navlist-bookmarks',
+;;    `bmkp-light-non-autonamed-this-buffer',
+;;    `bmkp-light-this-buffer', `bmkp-lighted-jump',
+;;    `bmkp-lighted-jump-other-window', `bmkp-lighted-jump-to-list',
+;;    `bmkp-next-lighted-this-buffer',
+;;    `bmkp-next-lighted-this-buffer-repeat',
+;;    `bmkp-previous-lighted-this-buffer',
+;;    `bmkp-previous-lighted-this-buffer-repeat',
+;;    `bmkp-set-lighting-for-bookmark',
+;;    `bmkp-set-lighting-for-buffer',
+;;    `bmkp-set-lighting-for-this-buffer',
+;;    `bmkp-toggle-auto-light-when-jump',
+;;    `bmkp-toggle-auto-light-when-set',
+;;    `bmkp-unlight-autonamed-this-buffer', `bmkp-unlight-bookmark',
+;;    `bmkp-unlight-bookmark-here',
+;;    `bmkp-unlight-bookmark-this-buffer', `bmkp-unlight-bookmarks',
+;;    `bmkp-unlight-non-autonamed-this-buffer',
+;;    `bmkp-unlight-this-buffer'.
+;;
+;;  User options defined here:
+;;
+;;    `bmkp-auto-light-relocate-when-jump-flag',
+;;    `bmkp-auto-light-when-jump', `bmkp-auto-light-when-set',
+;;    `bmkp-light-left-fringe-bitmap' (Emacs 22+),
+;;    `bmkp-light-priorities', `bmkp-light-right-fringe-bitmap' (Emacs
+;;    22+), `bmkp-light-style-autonamed',
+;;    `bmkp-light-style-non-autonamed', `bmkp-light-threshold',
+;;    `bmkp-tooltip-content-function'.
+;;
+;;  Faces defined here:
+;;
+;;    `bmkp-light-autonamed', `bmkp-light-fringe-autonamed' (Emacs
+;;    22+), `bmkp-light-fringe-non-autonamed' (Emacs 22+),
+;;    `bmkp-light-mark', `bmkp-light-non-autonamed'.
+;;
+;;  Non-interactive functions defined here:
+;;
+;;    `bmkp--pop-to-buffer-same-window',
+;;    `bmkp-a-bookmark-lighted-at-pos',
+;;    `bmkp-a-bookmark-lighted-on-this-line',
+;;    `bmkp-bookmark-data-from-record',
+;;    `bmkp-bookmark-name-from-record', `bmkp-bookmark-overlay-p',
+;;    `bmkp-default-lighted', `bmkp-fringe-string' (Emacs 22+),
+;;    `bmkp-get-lighting', `bmkp-lighted-p', `bmkp-light-face',
+;;    `bmkp-light-style', `bmkp-light-style-choices',
+;;    `bmkp-light-when', `bmkp-lighted-alist-only',
+;;    `bmkp-lighting-attribute', `bmkp-lighting-face',
+;;    `bmkp-lighting-style', `bmkp-lighting-when',
+;;    `bmkp-make/move-fringe' (Emacs 22+),
+;;    `bmkp-make/move-overlay-of-style', `bmkp-number-lighted',
+;;    `bmkp-overlay-of-bookmark', `bmkp-read-set-lighting-args',
+;;    `bmkp-set-lighting-for-bookmarks',
+;;    `bmkp-this-buffer-lighted-alist-only',
+;;    `bookmark-name-from-full-record', `bookmark-name-from-record'.
+;;
+;;  Internal variables defined here:
+;;
+;;    `bmkp-autonamed-overlays', `bmkp-last-auto-light-when-jump',
+;;    `bmkp-last-auto-light-when-set', `bmkp-light-styles-alist',
+;;    `bmkp-non-autonamed-overlays'.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 3, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;
+
+(eval-when-compile (require 'cl)) ;; case (plus, for Emacs 20: push)
+
+(require 'bookmark)
+;; bookmark-alist, bookmark-bmenu-bookmark, bookmark-completing-read, bmkp-get-bookmark,
+;; bookmark-get-position, bookmark-handle-bookmark, bookmark-maybe-load-default-file,
+;; bookmark-name-from-full-record, bookmark-name-from-record, bookmark-prop-get, bookmark-prop-set
+
+
+;; Some general Renamings.
+;;
+;; 1. Fix incompatibility introduced by gratuitous Emacs name change.
+;;
+(cond ((and (fboundp 'bookmark-name-from-record)  (not (fboundp 'bookmark-name-from-full-record)))
+       (defalias 'bookmark-name-from-full-record 'bookmark-name-from-record))
+      ((and (fboundp 'bookmark-name-from-full-record)  (not (fboundp 'bookmark-name-from-record)))
+       (defalias 'bookmark-name-from-record 'bookmark-name-from-full-record)))
+
+;; 2. The vanilla name of the first is misleading, as it returns only the cdr of the record.
+;;    The second is for consistency.
+;;
+(defalias 'bmkp-bookmark-data-from-record 'bookmark-get-bookmark-record)
+(defalias 'bmkp-bookmark-name-from-record 'bookmark-name-from-full-record)
+
+
+(eval-when-compile
+ (or (condition-case nil
+         (load-library "bookmark+-mac") ; Use load-library to ensure latest .elc.
+       (error nil))
+     (require 'bookmark+-mac)))         ; Require, so can load separately if not on `load-path'.
+;; bmkp-define-show-only-command
+
+
+;; (eval-when-compile (require 'bookmark+-bmu))
+;; bmkp-bmenu-barf-if-not-in-menu-list, bmkp-bmenu-filter-function,
+;; bmkp-bmenu-title
+
+;; (eval-when-compile (require 'bookmark+-1))
+;; bmkp-autonamed-bookmark-p, bmkp-autonamed-this-buffer-alist-only,
+;; bmkp-autoname-format, bmkp-current-nav-bookmark,
+;; bmkp-current-sort-order, bmkp-cycle-1, bmkp-default-bookmark-name,
+;; bmkp-function-bookmark-p, bmkp-get-bookmark-in-alist, bmkp-get-buffer-name, bmkp-jump-1,
+;; bmkp-latest-bookmark-alist, bmkp-marked-bookmarks-only,
+;; bmkp-msg-about-sort-order, bmkp-nav-alist, bmkp-refresh-menu-list,
+;; bmkp-remove-if, bmkp-remove-if-not, bmkp-repeat-command,
+;; bmkp-sequence-bookmark-p, bmkp-sort-omit,
+;; bmkp-specific-buffers-alist-only, bmkp-this-buffer-alist-only,
+;; bmkp-this-file/buffer-cycle-sort-comparer, bmkp-this-buffer-p
+
+(require 'pp+ nil t) ;; pp-read-expression-map
+
+;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Quiet the byte-compiler
+;;
+(defvar bmkp-autoname-format)           ; In `bookmark+-1.el'.
+(defvar bmkp-bmenu-buffer)              ; In `bookmark+.el'
+(defvar bmkp-current-nav-bookmark)      ; In `bookmark+-1.el'.
+(defvar bmkp-latest-bookmark-alist)     ; In `bookmark+-1.el'.
+(defvar bmkp-light-left-fringe-bitmap)  ; Defined in this file for Emacs 22+.
+(defvar bmkp-light-right-fringe-bitmap) ; Defined in this file for Emacs 22+.
+(defvar bmkp-nav-alist)                 ; In `bookmark+-1.el'.
+(defvar bmkp-this-file/buffer-cycle-sort-comparer) ; In `bookmark+-1.el'.
+(defvar fringe-bitmaps)                 ; Built-in for Emacs 22+.
+
+ 
+;;(@* "Faces (Customizable)")
+;;; Faces (Customizable) ---------------------------------------------
+
+(defface bmkp-light-autonamed
+    '((((background dark)) (:background "#00004AA652F1")) ; a dark cyan
+      (t (:background "misty rose")))   ; a light pink
+  "*Face used to highlight an autonamed bookmark (except in the fringe)."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-light-autonamed-region
+    '((((background dark)) (:background "#22225F5F2222")) ; a dark green
+      (t (:background "plum")))   ; a light magenta
+  "*Face used to highlight an autonamed bookmark (except in the fringe)."
+  :group 'bookmark-plus :group 'faces)
+
+(when (fboundp 'fringe-columns)
+  (defface bmkp-light-fringe-autonamed
+      '((((background dark)) (:background "#B19E6A64B19E")) ; a dark magenta
+        (t (:background "#691DC8A2691D"))) ; a medium green
+    "*Face used to highlight an autonamed bookmark in the fringe."
+    :group 'bookmark-plus :group 'faces)
+  (defface bmkp-light-fringe-non-autonamed
+      '((((background dark)) (:background "#691DC8A2691D")) ; a medium green
+        (t (:foreground "Black" :background "Plum"))) ; a light magenta
+    "*Face used to highlight a non-autonamed bookmark in the fringe."
+    :group 'bookmark-plus :group 'faces))
+
+(defface bmkp-light-mark '((t (:background "Plum")))
+  "*Face used to mark bookmarks with highlight overrides, in bookmark list.
+This face must be combinable with face `bmkp-t-mark'."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-light-non-autonamed
+    '((((background dark)) (:background "#B19E6A64B19E")) ; a dark magenta
+      (t (:background "DarkSeaGreen1"))) ; a light green
+  "*Face used to highlight a non-autonamed bookmark (except in the fringe)."
+  :group 'bookmark-plus :group 'faces)
+
+(defface bmkp-light-non-autonamed-region
+    '((((background dark)) (:background "#BFBF1F1F2F2F")) ; a dark red
+      (t (:background "turquoise")))
+  "*Face used to highlight a non-autonamed bookmark (except in the fringe)."
+  :group 'bookmark-plus :group 'faces)
+
+;; Emacs bug # prevents making use of a face in a tooltip.
+;;
+;; (defface bmkp-tooltip-content-face
+;;   '((((class color))
+;;      :background "lightyellow"
+;;      :foreground "black"
+;;      :family     "Courier")
+;;     (t
+;;      :family     "Courier"))
+;;   "Face for mouseover tooltip content for highlighted bookmarks."
+;;   :group 'bookmark-plus :group 'faces :group 'tooltip)
+ 
+;;(@* "User Options (Customizable)")
+;;; User Options (Customizable) --------------------------------------
+
+;;;###autoload (autoload 'bmkp-auto-light-relocate-when-jump-flag "bookmark+")
+(defcustom bmkp-auto-light-relocate-when-jump-flag t
+  "*Non-nil means highlight the relocated, instead of the recorded, position.
+This has an effect only when the highlighting style for the bookmark
+is `point'."
+  :type 'boolean :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-auto-light-when-jump "bookmark+")
+(defcustom bmkp-auto-light-when-jump nil
+  "*Which bookmarks to automatically highlight when jumped to.
+NOTE: The values that specify highlighting in the current buffer
+highlight bookmarks in the buffer that is current after jumping.  If
+the bookmark does not really have an associated buffer, for example a
+bookmark with a handler such as `w32-browser' that just invokes a
+separate, non-Emacs program, then the current buffer after jumping
+will be the buffer before jumping."
+  :type '(choice
+          (const :tag "Autonamed bookmark"                 autonamed-bookmark)
+          (const :tag "Non-autonamed bookmark"             non-autonamed-bookmark)
+          (const :tag "Any bookmark"                       any-bookmark)
+          (const :tag "Autonamed bookmarks in buffer"      autonamed-in-buffer)
+          (const :tag "Non-autonamed bookmarks in buffer"  non-autonamed-in-buffer)
+          (const :tag "All bookmarks in buffer"            all-in-buffer)
+          (const :tag "None (no automatic highlighting)"   nil))
+  :group 'bookmark-plus)
+
+;; The value is not correct if user customizes `bmkp-auto-light-when-jump' to non-nil.
+;; So must compensate in `bmkp-toggle-auto-light-when-jump'.
+(defvar bmkp-last-auto-light-when-jump (and (not bmkp-auto-light-when-jump)  'all-in-buffer)
+  "Last value of `bmkp-auto-light-when-jump'.")
+
+;;;###autoload (autoload 'bmkp-auto-light-when-set "bookmark+")
+(defcustom bmkp-auto-light-when-set nil
+  "*Which bookmarks to automatically highlight when set."
+  :type '(choice
+          (const :tag "Autonamed bookmark"                 autonamed-bookmark)
+          (const :tag "Non-autonamed bookmark"             non-autonamed-bookmark)
+          (const :tag "Any bookmark"                       any-bookmark)
+          (const :tag "Autonamed bookmarks in buffer"      autonamed-in-buffer)
+          (const :tag "Non-autonamed bookmarks in buffer"  non-autonamed-in-buffer)
+          (const :tag "All bookmarks in buffer"            all-in-buffer)
+          (const :tag "None (no automatic highlighting)"   nil))
+  :group 'bookmark-plus)
+
+;; The value is not correct if user customizes `bmkp-auto-light-when-set' to non-nil.
+;; So must compensate in `bmkp-toggle-auto-light-when-set'.
+(defvar bmkp-last-auto-light-when-set (and (not bmkp-auto-light-when-set)  'all-in-buffer)
+  "Last value of `bmkp-auto-light-when-set'.")
+
+;;;###autoload (autoload 'bmkp-light-priorities "bookmark+")
+(defcustom bmkp-light-priorities '((bmkp-autonamed-overlays        . 160)
+                                   (bmkp-non-autonamed-overlays    . 150))
+  "*Priorities of bookmark highlighting overlay types.
+As an idea, `isearch' uses 1000 and 1001."
+  :group 'bookmark-plus :type '(alist :key-type symbol :value-type integer))
+
+;; Not used for Emacs 20-21 or Emacs built without fringe support.
+(when (and (fboundp 'fringe-columns)  (boundp 'fringe-bitmaps))
+  (defcustom bmkp-light-left-fringe-bitmap 'left-triangle
+    "*Symbol for the left fringe bitmap to use to highlight a bookmark.
+This option is not used for Emacs versions before Emacs 22."
+    :type (cons 'choice (mapcar (lambda (bb) (list 'const bb)) fringe-bitmaps))
+    :group 'bookmark-plus)
+
+  ;; Not used for Emacs 20-21 or Emacs built without fringe support.
+  (defcustom bmkp-light-right-fringe-bitmap 'right-triangle
+    "*Symbol for the right fringe bitmap to use to highlight a bookmark.
+This option is not used for Emacs versions before Emacs 22."
+    :type (cons 'choice (mapcar (lambda (bb) (list 'const bb)) fringe-bitmaps))
+    :group 'bookmark-plus))
+
+;; Must be before any options that use it.
+(defvar bmkp-light-styles-alist (append '(("Region"              . region)
+                                          ("Line Beginning"      . bol)
+                                          ("Position"            . point)
+                                          ("Line"                . line)
+                                          ("None"                . none))
+                                        (and (fboundp 'fringe-columns)
+                                             '(("Left Fringe"         . lfringe)
+                                               ("Right Fringe"        . rfringe)
+                                               ("Left Fringe + Line"  . line+lfringe)
+                                               ("Right Fringe + Line" . line+rfringe))))
+  "Alist of highlighting styles.  Key: string description.  Value: symbol.")
+
+;; Must be before options that use it.
+(defun bmkp-light-style-choices ()
+  "Return custom `:type' used for bookmark highlighting style choices."
+  (cons 'choice
+        (mapcar (lambda (xx) (list 'const :tag (car xx) (cdr xx))) bmkp-light-styles-alist)))
+
+;;;###autoload (autoload 'bmkp-light-style-autonamed "bookmark+")
+(defcustom bmkp-light-style-autonamed (if (not (fboundp 'fringe-columns)) ; Emacs 20-21.
+                                          'line
+                                        'line+lfringe)
+  "*Default highlight style for autonamed bookmarks."
+  :group 'bookmark-plus :type (bmkp-light-style-choices))
+
+;;;###autoload (autoload 'bmkp-light-style-non-autonamed "bookmark+")
+(defcustom bmkp-light-style-non-autonamed (if (not (fboundp 'fringe-columns)) ; Emacs 20-21.
+                                              'line
+                                            'line+rfringe)
+  "*Default highlight style for non-autonamed bookmarks."
+  :group 'bookmark-plus :type (bmkp-light-style-choices))
+
+;;;###autoload (autoload 'bmkp-light-style-autonamed-region "bookmark+")
+(defcustom bmkp-light-style-autonamed-region  'region
+  "*Default highlight style for autonamed region bookmarks."
+  :group 'bookmark-plus :type (bmkp-light-style-choices))
+
+;;;###autoload (autoload 'bmkp-light-style-non-autonamed-region "bookmark+")
+(defcustom bmkp-light-style-non-autonamed-region 'region
+  "*Default highlight style for non-autonamed region bookmarks."
+  :group 'bookmark-plus :type (bmkp-light-style-choices))
+
+;;;###autoload (autoload 'bmkp-light-threshold "bookmark+")
+(defcustom bmkp-light-threshold 100000
+  "*Maximum number of bookmarks to highlight."
+  :type 'integer :group 'bookmark-plus)
+
+;;;###autoload (autoload 'bmkp-tooltip-content-function "bookmark+")
+(defcustom bmkp-tooltip-content-function 'bmkp-bookmark-description
+  "Function providing mouseover tooltip content for highlighted bookmarks.
+It should accept a bookmark name or record as its first arg and return
+a value acceptable as a `help-echo' property value.
+
+One alternative to the default value of `bmkp-bookmark-description' is
+`bmkp-annotation-or-bookmark-description', which shows the bookmark
+annotation if there is one, or the full description if not.
+
+To prevent showing any tooltip you can use a function, such as
+`ignore', that returns nil."
+  :type 'function :group 'bookmark-plus :group 'tooltip)
+ 
+;;(@* "Internal Variables")
+;;; Internal Variables -----------------------------------------------
+
+(defvar bmkp-autonamed-overlays nil
+  "Overlays used to highlight autonamed bookmarks.")
+
+(defvar bmkp-non-autonamed-overlays nil
+  "Overlays used to highlight non-autonamed bookmarks.")
+ 
+;;(@* "Functions")
+;;; Functions --------------------------------------------------------
+
+
+;;(@* "Menu-List (`*-bmenu-*') Commands")
+;;  *** Menu-List (`*-bmenu-*') Commands ***
+
+;;;###autoload (autoload 'bmkp-bmenu-show-only-lighted-bookmarks "bookmark+")
+(bmkp-define-show-only-command lighted "Display (only) the highlighted bookmarks." ; `H S' in bookmark list
+                               bmkp-lighted-alist-only)
+
+;;;###autoload (autoload 'bmkp-bmenu-light "bookmark+")
+(defun bmkp-bmenu-light ()              ; `H H' in bookmark list
+  "Highlight the location of this line's bookmark."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bmkp-light-bookmark (bookmark-bmenu-bookmark) nil nil 'MSG))
+
+;;;###autoload (autoload 'bmkp-bmenu-light-marked "bookmark+")
+(defun bmkp-bmenu-light-marked (&optional parg msgp) ; `H > H' in bookmark list
+  "Highlight the marked bookmarks."
+  (interactive (list 'MSG))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (when msgp (message "Highlighting marked bookmarks..."))
+  (let ((marked  (bmkp-marked-bookmarks-only)))
+    (unless marked (error "No marked bookmarks"))
+    (dolist (bmk  marked) (bmkp-light-bookmark bmk)))
+  (when msgp (message "Highlighting marked bookmarks...done")))
+
+;;;###autoload (autoload 'bmkp-bmenu-unlight "bookmark+")
+(defun bmkp-bmenu-unlight ()            ; `H U' in bookmark list
+  "Unhighlight the location of this line's bookmark."
+  (interactive)
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bmkp-unlight-bookmark (bookmark-bmenu-bookmark) 'NOERROR))
+
+;;;###autoload (autoload 'bmkp-bmenu-unlight-marked "bookmark+")
+(defun bmkp-bmenu-unlight-marked (&optional parg msgp) ; `H > U' in bookmark list
+  "Unhighlight the marked bookmarks."
+  (interactive (list 'MSG))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (when msgp (message "Unhighlighting marked bookmarks..."))
+  (let ((marked  (bmkp-marked-bookmarks-only)))
+    (unless marked (error "No marked bookmarks"))
+    (dolist (bmk  marked) (bmkp-unlight-bookmark bmk t)))
+  (when msgp (message "Unhighlighting marked bookmarks...done")))
+
+;;;###autoload (autoload 'bmkp-bmenu-set-lighting "bookmark+")
+(defun bmkp-bmenu-set-lighting (style face when &optional msgp) ; `H +' in bookmark list
+  "Set the `lighting' entry for this line's bookmark.
+You are prompted for the highlight STYLE, FACE, and condition (WHEN)
+that make up the property-list value of the `lighting' entry."
+  (interactive
+   (let* ((bmk        (bookmark-bmenu-bookmark))
+          (bmk-style  (bmkp-lighting-style bmk))
+          (bmk-face   (bmkp-lighting-face bmk))
+          (bmk-when   (bmkp-lighting-when bmk)))
+     (append (bmkp-read-set-lighting-args
+              (and bmk-style  (format "%s" (car (rassq bmk-style bmkp-light-styles-alist))))
+              (and bmk-face   (format "%S" bmk-face))
+              (and bmk-when   (format "%S" bmk-when)))
+             '(MSG))))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (bmkp-set-lighting-for-bookmark (bookmark-bmenu-bookmark) style face when 'MSG))
+
+;;;###autoload (autoload 'bmkp-bmenu-set-lighting-for-marked "bookmark+")
+(defun bmkp-bmenu-set-lighting-for-marked (style face when &optional msgp) ; `H > +' in bookmark list
+  "Set the `lighting' entry for the marked bookmarks.
+You are prompted for the highlight STYLE, FACE, and condition (WHEN)."
+  (interactive (append (bmkp-read-set-lighting-args) '(MSG)))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (when msgp (message "Setting highlighting..."))
+  (let ((marked    (bmkp-marked-bookmarks-only))
+        (curr-bmk  (bookmark-bmenu-bookmark)))
+    (unless marked (error "No marked bookmarks"))
+    (dolist (bmk  marked)
+      (bookmark-prop-set bmk 'lighting (if (or face  style  when)
+                                           `(,@(and face   (not (eq face 'auto))   `(:face ,face))
+                                             ,@(and style  (not (eq style 'none))  `(:style ,style))
+                                             ,@(and when   (not (eq when 'auto))   `(:when ,when)))
+                                         ())))
+    (when (get-buffer-create bmkp-bmenu-buffer) (bmkp-refresh-menu-list curr-bmk)))
+  (when msgp (message "Setting highlighting...done")))
+
+
+;;(@* "General Highlight Commands")
+;;  *** General Highlight Commands ***
+
+;;;###autoload (autoload 'bmkp-bookmarks-lighted-at-point "bookmark+")
+(defun bmkp-bookmarks-lighted-at-point (&optional position fullp msgp) ; `C-x p ='
+  "Return a list of the bookmarks highlighted at point.
+Include only those in the current bookmark list (`bookmark-alist').
+With no prefix arg, return the bookmark names.
+With a prefix arg, return the full bookmark data.
+Interactively, display the info.
+Non-interactively:
+ Use the bookmarks at optional arg POSITION (default: point).
+ Optional arg FULLP means return full bookmark data.
+ Optional arg MSGP means display the info."
+  (interactive (list (point) current-prefix-arg 'MSG))
+  (unless position (setq position  (point)))
+  (let ((bmks  ())
+        bmk)
+    (dolist (ov  (overlays-at position))
+      (when (setq bmk  (overlay-get ov 'bookmark))
+        (when (setq bmk  (bmkp-get-bookmark-in-alist bmk 'NOERROR)) ; Ensure it's in current bookmark list.
+          (push (if fullp bmk (bmkp-bookmark-name-from-record bmk)) bmks))))
+    (if (not fullp)
+        (when msgp (message "%s" bmks))
+      (setq bmks  (mapcar #'bmkp-get-bookmark bmks))
+      (when msgp (pp-eval-expression 'bmks)))
+    bmks))
+
+;;;###autoload (autoload 'bmkp-toggle-auto-light-when-jump "bookmark+")
+(defun bmkp-toggle-auto-light-when-jump (&optional msgp) ; Not bound.
+  "Toggle automatic bookmark highlighting when a bookmark is jumped to.
+Set option `bmkp-auto-light-when-jump' to nil if non-nil, and to its
+last non-nil value if nil."
+  (interactive "p")
+  (when (and bmkp-auto-light-when-jump  bmkp-last-auto-light-when-jump) ; Compensate for wrong default
+    (setq bmkp-last-auto-light-when-jump  nil))
+  (setq bmkp-last-auto-light-when-jump
+        (prog1 bmkp-auto-light-when-jump ; Swap
+          (setq bmkp-auto-light-when-jump  bmkp-last-auto-light-when-jump)))
+  (when msgp (message "Automatic highlighting of bookmarks when jumping is now %s"
+                      (if bmkp-auto-light-when-jump
+                          (upcase (symbol-name bmkp-auto-light-when-jump))
+                        "OFF"))))
+                                        
+;;;###autoload (autoload 'bmkp-lighted-jump "bookmark+")
+(defun bmkp-lighted-jump (bookmark-name &optional flip-use-region-p) ; `C-x j h'
+  "Jump to a highlighted bookmark.
+This is a specialization of `bookmark-jump' - see that, in particular
+for info about using a prefix argument."
+  (interactive
+   (let ((alist  (bmkp-lighted-alist-only)))
+     (unless alist  (error "No highlighted bookmarks"))
+     (list (bookmark-completing-read "Jump to highlighted bookmark" nil alist) current-prefix-arg)))
+  (bmkp-jump-1 bookmark-name 'bmkp--pop-to-buffer-same-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-lighted-jump-other-window "bookmark+")
+(defun bmkp-lighted-jump-other-window (bookmark-name &optional flip-use-region-p) ; `C-x 4 j h'
+  "Jump to a highlighted bookmark in another window.
+See `bmkp-lighted-jump'."
+  (interactive
+   (let ((alist  (bmkp-lighted-alist-only)))
+     (unless alist  (error "No highlighted bookmarks"))
+     (list (bookmark-completing-read "Jump to highlighted bookmark in another window" nil alist)
+           current-prefix-arg)))
+  (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window flip-use-region-p))
+
+;;;###autoload (autoload 'bmkp-lighted-jump-to-list "bookmark+")
+(defun bmkp-lighted-jump-to-list (bookmark &optional position msgp) ; Not bound.
+  "Jump to location in `*Bookmark List*' for a lighted bookmark at point.
+You are prompted for BOOKMARK (a bookmark name).
+Completion candidates are the lighted bookmarks at point."
+  (interactive (let* ((bmks    (bmkp-bookmarks-lighted-at-point (point) nil 'MSG))
+                      (IGNORE  (unless bmks (error "No highlighted bookmarks at point")))
+                      (bmk   (bookmark-completing-read "Bookmark" (car bmks) bmks)))
+                 (list bmk (point) t)))
+  (pop-to-buffer (get-buffer-create bmkp-bmenu-buffer))
+  (bookmark-bmenu-list)
+  (bmkp-bmenu-goto-bookmark-named (setq bmkp-last-bmenu-bookmark  bookmark)))
+
+;;;###autoload (autoload 'bmkp-unlight-bookmark "bookmark+")
+(defun bmkp-unlight-bookmark (bookmark &optional noerrorp msgp) ; Not bound
+  "Unhighlight BOOKMARK.
+BOOKMARK is a bookmark name or a bookmark record."
+  (interactive
+   (let ((lighted-bmks  (bmkp-lighted-alist-only)))
+     (unless lighted-bmks (error "No highlighted bookmarks"))
+     (list (bookmark-completing-read "UNhighlight bookmark" (bmkp-default-lighted) lighted-bmks)
+           nil
+           'MSG)))
+  (let* ((bmk         (bmkp-get-bookmark bookmark 'NOERROR))
+         (bmk-name    (bmkp-bookmark-name-from-record bmk))
+         (autonamedp  (and bmk  (bmkp-autonamed-bookmark-p bmk))))
+    (when bmk                           ; Skip bad bookmark, but not already highlighted bookmark.
+      (unless (or noerrorp  (bmkp-lighted-p bmk-name)) (error "Bookmark `%s' is not highlighted" bmk-name))
+      (dolist (ov  (if autonamedp bmkp-autonamed-overlays bmkp-non-autonamed-overlays))
+        (when (eq bmk (overlay-get ov 'bookmark))  (delete-overlay ov)))) ; Check full bookmark, not name.
+    (when msgp (message "UNhighlighted bookmark `%s'" bmk-name))))
+
+;;;###autoload (autoload 'bmkp-unlight-bookmark-here "bookmark+")
+(defun bmkp-unlight-bookmark-here (&optional noerrorp msgp) ; `C-x p C-u'
+  "Unhighlight a bookmark at point or the same line (in that order)."
+  (interactive (list nil 'MSG))
+  (let ((bmk  (or (bmkp-a-bookmark-lighted-at-pos)  (bmkp-a-bookmark-lighted-on-this-line))))
+    (unless bmk (error "No highlighted bookmark on this line"))
+    (bmkp-unlight-bookmark bmk noerrorp msgp)))
+
+;;;###autoload (autoload 'bmkp-unlight-bookmark-this-buffer "bookmark+")
+(defun bmkp-unlight-bookmark-this-buffer (bookmark &optional noerrorp msgp) ; `C-x p u'
+  "Unhighlight a BOOKMARK in this buffer.
+BOOKMARK is a bookmark name or a bookmark record.
+With a prefix arg, choose from all lighted bookmarks, not just those
+in this buffer."
+  (interactive
+   (let ((lighted-bmks  (if current-prefix-arg
+                            (bmkp-lighted-alist-only)
+                          (bmkp-this-buffer-lighted-alist-only)))
+         (msg-suffix    (if current-prefix-arg "" " in this buffer")))
+     (unless lighted-bmks (error "No highlighted bookmarks%s" msg-suffix))
+     (list (bookmark-completing-read (format "UNhighlight bookmark%s in this buffer" msg-suffix)
+                                     (bmkp-default-lighted)
+                                     lighted-bmks
+                                     nil
+                                     nil
+                                     'USE-NIL-ALIST-P)
+           nil
+           'MSG)))
+  (bmkp-unlight-bookmark bookmark noerrorp msgp))
+
+;;;###autoload (autoload 'bmkp-unlight-bookmarks "bookmark+")
+(defun bmkp-unlight-bookmarks (&optional overlays-symbols this-buffer-p msgp) ; `C-x p U'
+  "Unhighlight lighted bookmarks.
+A prefix argument determines which bookmarks to unhighlight:
+ none    - Current buffer, all lighted bookmarks.
+ >= 0    - Current buffer, only autonamed lighted bookmarks.
+ < 0     - Current buffer, only non-autonamed lighted bookmarks.
+ C-u     - All buffers (all lighted bookmarks)."
+  (interactive (list (cond ((or (not current-prefix-arg)  (consp current-prefix-arg))
+                            '(bmkp-autonamed-overlays bmkp-non-autonamed-overlays))
+                           ((natnump current-prefix-arg) '(bmkp-autonamed-overlays))
+                           (current-prefix-arg           '(bmkp-non-autonamed-overlays)))
+                     (or (not current-prefix-arg)  (atom current-prefix-arg))
+                     'MSG))
+  (unless overlays-symbols
+    (setq overlays-symbols  '(bmkp-autonamed-overlays bmkp-non-autonamed-overlays)))
+  (let ((count           0)
+        (count-auto      0)
+        (count-non-auto  0)
+        (this-buf        (current-buffer)))
+    (dolist (ov-symb  overlays-symbols)
+      (dolist (ov  (symbol-value ov-symb))
+        (let ((ov-buf  (overlay-buffer ov)))
+          (when (and ov-buf  (or (not this-buffer-p)  (eq ov-buf this-buf)))
+            (when (eq 'bmkp-autonamed-overlays ov-symb)
+              (setq count-auto  (1+ count-auto)
+                    count       (1+ count)))
+            (when (eq 'bmkp-non-autonamed-overlays ov-symb)
+              (setq count-non-auto  (1+ count-non-auto)
+                    count           (1+ count)))
+            (delete-overlay ov)))))
+    (when msgp (message "UNhighlighted %d bookmarks %s: %d autonamed, %d other"
+                        count (if this-buffer-p "in this buffer" "(all buffers)")
+                        count-auto count-non-auto))))
+
+;;;###autoload (autoload 'bmkp-unlight-autonamed-this-buffer "bookmark+")
+(defun bmkp-unlight-autonamed-this-buffer (&optional everywherep) ; Not bound
+  "Unhighlight autonamed bookmarks.
+No prefix arg: unhighlight them only in the current buffer.
+Prefix arg, unhighlight them everywhere."
+  (interactive "P")
+  (bmkp-unlight-bookmarks '(bmkp-autonamed-overlays) (not everywherep)))
+
+;;;###autoload (autoload 'bmkp-unlight-non-autonamed-this-buffer "bookmark+")
+(defun bmkp-unlight-non-autonamed-this-buffer (&optional everywherep) ; Not bound
+  "Unhighlight non-autonamed bookmarks.
+No prefix arg: unhighlight them only in the current buffer.
+Prefix arg, unhighlight them everywhere."
+  (interactive "P")
+  (bmkp-unlight-bookmarks '(bmkp-non-autonamed-overlays) (not everywherep)))
+
+;;;###autoload (autoload 'bmkp-unlight-this-buffer "bookmark+")
+(defun bmkp-unlight-this-buffer ()      ; Not bound
+  "Unhighlight all bookmarks in the current buffer."
+  (interactive)
+  (bmkp-unlight-bookmarks))
+
+;;;###autoload (autoload 'bmkp-toggle-auto-light-when-set "bookmark+")
+(defun bmkp-toggle-auto-light-when-set (&optional msgp) ; Not bound.
+  "Toggle automatic bookmark highlighting when a bookmark is set.
+Set option `bmkp-auto-light-when-set' to nil if non-nil, and to its
+last non-nil value if nil."
+  (interactive "p")
+  (when (and bmkp-auto-light-when-set  bmkp-last-auto-light-when-set) ; Compensate for wrong default
+    (setq bmkp-last-auto-light-when-set  nil))
+  (setq bmkp-last-auto-light-when-set  (prog1 bmkp-auto-light-when-set ; Swap
+                                         (setq bmkp-auto-light-when-set  bmkp-last-auto-light-when-set)))
+  (when msgp (message "Automatic highlighting of bookmarks when setting is now %s"
+                      (if bmkp-auto-light-when-set
+                          (upcase (symbol-name bmkp-auto-light-when-set))
+                        "OFF"))))
+                                        
+;;;###autoload (autoload 'bmkp-set-lighting-for-bookmark "bookmark+")
+(defun bmkp-set-lighting-for-bookmark (bookmark-name style face when &optional msgp light-now-p) ; Not bound
+  "Set the `lighting' entry for bookmark BOOKMARK-NAME.
+You are prompted for the bookmark, highlight STYLE, FACE, and
+condition (WHEN) that make up the property-list value of the
+`lighting' entry.
+
+With a prefix argument, do not highlight now.
+
+Non-interactively:
+STYLE, FACE, and WHEN are as for a bookmark's `lighting' entry
+  properties, or nil if no such property.
+Non-nil MSGP means display a highlighting progress message.
+Non-nil LIGHT-NOW-P means apply the highlighting now."
+  (interactive
+   (let* ((bmk        (bookmark-completing-read "Highlight bookmark"
+                                                (or (bmkp-default-lighted)  (bmkp-default-bookmark-name))))
+          (bmk-style  (bmkp-lighting-style bmk))
+          (bmk-face   (bmkp-lighting-face bmk))
+          (bmk-when   (bmkp-lighting-when bmk)))
+     (append (list bmk)
+             (bmkp-read-set-lighting-args
+              (and bmk-style  (format "%s" (car (rassq bmk-style bmkp-light-styles-alist))))
+              (and bmk-face   (format "%S" bmk-face))
+              (and bmk-when   (format "%S" bmk-when)))
+             (list 'MSGP (not current-prefix-arg)))))
+  (when msgp (message "Setting highlighting..."))
+  (bookmark-prop-set bookmark-name 'lighting (if (or face  style  when)
+                                                 `(,@(and face   (not (eq face 'auto))   `(:face ,face))
+                                                   ,@(and style  (not (eq style 'none))  `(:style ,style))
+                                                   ,@(and when   (not (eq when 'auto))   `(:when ,when)))
+                                               ()))
+  (when (get-buffer-create bmkp-bmenu-buffer) (bmkp-refresh-menu-list bookmark-name))
+  (when msgp (message "Setting highlighting...done"))
+  (when light-now-p (bmkp-light-bookmark bookmark-name nil nil msgp))) ; This msg is more informative.
+
+;;;###autoload (autoload 'bmkp-set-lighting-for-buffer "bookmark+")
+(defun bmkp-set-lighting-for-buffer (buffer style face when &optional msgp light-now-p) ; Not bound
+  "Set the `lighting' entry for each of the bookmarks for BUFFER.
+You are prompted for the highlight STYLE, FACE, and condition (WHEN).
+With a prefix argument, do not highlight now.
+
+Non-interactively:
+STYLE, FACE, and WHEN are as for a bookmark's `lighting' entry
+  properties, or nil if no such property.
+Non-nil MSGP means display a highlighting progress message.
+Non-nil LIGHT-NOW-P means apply the highlighting now."
+  (interactive (append (list (bmkp-completing-read-buffer-name))
+                       (bmkp-read-set-lighting-args)
+                       (list 'MSGP (not current-prefix-arg))))
+  (bmkp-set-lighting-for-bookmarks
+   (let ((bmkp-last-specific-buffer  buffer)) (bmkp-last-specific-buffer-alist-only))
+   style face when msgp light-now-p))
+
+;;;###autoload (autoload 'bmkp-set-lighting-for-this-buffer "bookmark+")
+(defun bmkp-set-lighting-for-this-buffer (style face when &optional msgp light-now-p) ; Not bound
+  "Set the `lighting' entry for each of the bookmarks for this buffer.
+You are prompted for the highlight STYLE, FACE, and condition (WHEN).
+With a prefix argument, do not highlight now.
+
+Non-interactively:
+STYLE, FACE, and WHEN are as for a bookmark's `lighting' entry
+  properties, or nil if no such property.
+Non-nil MSGP means display a highlighting progress message.
+Non-nil LIGHT-NOW-P means apply the highlighting now."
+  (interactive (append (bmkp-read-set-lighting-args) (list 'MSGP (not current-prefix-arg))))
+  (bmkp-set-lighting-for-bookmarks (bmkp-this-buffer-alist-only) style face when msgp light-now-p))
+
+(defun bmkp-set-lighting-for-bookmarks (alist style face when &optional msgp light-now-p)
+  "Set the `lighting' entry for each of the bookmarks in ALIST.
+STYLE, FACE, and WHEN are as for a bookmark's `lighting' entry
+  properties, or nil if no such property.
+Non-nil MSGP means display a highlighting progress message.
+Non-nil LIGHT-NOW-P means apply the highlighting now."
+  (when msgp (message "Setting highlighting..."))
+  (dolist (bmk  alist) (bmkp-set-lighting-for-bookmark bmk style face when)) ; No MSGP arg here.
+  (when msgp (message "Setting highlighting...done"))
+  (when light-now-p (bmkp-light-bookmarks alist nil msgp))) ; Do separately so we get its message.
+
+;;;###autoload (autoload 'bmkp-light-bookmark "bookmark+")
+(defun bmkp-light-bookmark (bookmark &optional style face msgp pointp) ; Not bound
+  "Highlight BOOKMARK.
+With a prefix arg you are prompted for the style and/or face to use:
+ Plain prefix arg (`C-u'): prompt for both style and face.
+ Numeric non-negative arg: prompt for face.
+ Numeric negative arg: prompt for style.
+
+Non-interactively:
+ BOOKMARK is a bookmark name or a bookmark record, or it is ignored.
+ STYLE and FACE override the defaults.
+ POINT-P non-nil means highlight point rather than the recorded
+  bookmark position."
+  (interactive
+   (let* ((bmk  (bookmark-completing-read "Highlight bookmark" (bmkp-default-bookmark-name)))
+          (sty  (and current-prefix-arg  (or (consp current-prefix-arg)
+                                             (<= (prefix-numeric-value current-prefix-arg) 0))
+                     (cdr (assoc (let ((completion-ignore-case  t))
+                                   (completing-read
+                                    "Style: " bmkp-light-styles-alist nil t nil nil
+                                    (and (bmkp-lighting-style bmk)
+                                         (format "%s" (car (rassq (bmkp-lighting-style bmk)
+                                                                  bmkp-light-styles-alist))))))
+                                 bmkp-light-styles-alist))))
+          (fac  (and current-prefix-arg  (or (consp current-prefix-arg)
+                                             (natnump (prefix-numeric-value current-prefix-arg)))
+                     (not (member sty '(lfringe rfringe none))) ; No face possible for these.
+                     (condition-case nil ; Emacs 22+ accepts a default.
+                         (read-face-name "Face: " (format "%S" (bmkp-lighting-face  bmk)))
+                       (wrong-number-of-arguments (read-face-name "Face: "))))))
+     (list bmk sty fac 'MSG)))
+  (let* ((bmkp-use-region  nil)         ; Inhibit region handling.
+         (bmk              (bmkp-get-bookmark bookmark (not msgp))) ; Error if interactive.
+         (bmk-name         (bmkp-bookmark-name-from-record bmk))
+         (pos              (and bmk  (bookmark-get-position bmk)))
+         (buf              (and bmk  (bmkp-get-buffer-name bmk)))
+         (autonamedp       (and bmk  (bmkp-autonamed-bookmark-p bmk)))
+         (styl             (or style  (and bmk  (bmkp-light-style bmk))))
+         (fac              (or face   (and bmk
+                                           (not (member styl '(lfringe rfringe none)))
+                                           (bmkp-light-face  bmk))))
+         (passes-when-p    (and bmk  (or face
+                                         style ; Always highlight if changed face or style.
+                                         (bmkp-light-when bmk))))
+         (nb-lit           (bmkp-number-lighted))
+         bmk-ov)
+    (catch 'bmkp-light-bookmark
+      (when bmk                         ; Just skip bad bookmark if not interactive.
+        (cond ((setq bmk-ov  (bmkp-overlay-of-bookmark bmk)) ; Already highlighted.
+               (if (not (or style  face))
+                   (when msgp           ; No-op batch.
+                     (error "Already highlighted - use prefix arg to change"))
+                 (when style (bmkp-make/move-overlay-of-style style pos autonamedp bmk bmk-ov))
+                 (when (and face  (not (memq styl '(lfringe rfringe none))))
+                   (overlay-put bmk-ov 'face face)))
+               (when msgp (message "%sighlighted bookmark `%s'" (if bmk-ov "H" "UNh") bmk-name)))
+              (passes-when-p
+               (save-excursion
+
+                 ;; See note in comments of `bmkp-light-bookmarks' - same considerations here.
+                 ;; (let ((bmkp-jump-display-function  nil)) (bookmark-handle-bookmark bmk))
+                 ;;
+                 (with-current-buffer (or (and buf  (get-buffer buf))
+                                          (current-buffer))
+
+                   ;; POINTP is non-nil when `bmkp-light-bookmark' is called from
+                   ;; `bookmark--jump-via'.
+                   (when (and pointp  bmkp-auto-light-relocate-when-jump-flag)
+                     (setq pos  (point)))
+                   (when (and pos  (< pos (point-max)))
+                     (let ((ov  (bmkp-make/move-overlay-of-style styl pos autonamedp bmk)))
+                       (when ov         ; nil means `none' style.
+                         (let ((ovs  (if autonamedp
+                                         'bmkp-autonamed-overlays
+                                       'bmkp-non-autonamed-overlays)))
+                           (push ov (symbol-value ovs)))
+                         (when (and (not (bmkp-lighted-p bmk))
+                                    (> (setq nb-lit  (1+ nb-lit)) bmkp-light-threshold))
+                           (setq nb-lit  (1- nb-lit))
+                           (throw 'bmkp-light-bookmark bmk))
+                         (overlay-put ov 'priority
+                                      (or (cdr (assoc (if autonamedp
+                                                          'bmkp-autonamed-overlays
+                                                        'bmkp-non-autonamed-overlays)
+                                                      bmkp-light-priorities))
+                                          (apply #'min (mapcar #'cdr bmkp-light-priorities))))
+                         (unless (memq styl '(lfringe rfringe none)) (overlay-put ov 'face fac))
+                         (overlay-put ov 'evaporate  t)
+                         (overlay-put ov 'category   'bookmark-plus)
+                         (overlay-put ov 'bookmark   bmk)) ; Use full bookmark, because name can change.
+                       (when msgp
+                         (message "%sighlighted bookmark `%s'" (if ov "H" "UNh") bmk-name)))))))
+              (t
+               (when msgp (message "Bookmark's condition canceled highlighting"))))))))
+
+;;;###autoload (autoload 'bmkp-light-bookmark-this-buffer "bookmark+")
+(defun bmkp-light-bookmark-this-buffer (bookmark &optional style face msgp) ; `C-x p h'
+  "Highlight a BOOKMARK in the current buffer.
+With a prefix arg you are prompted for the style and/or face to use:
+ Plain prefix arg (`C-u'): prompt for both style and face.
+ Numeric non-negative arg: prompt for face.
+ Numeric negative arg: prompt for style.
+See `bmkp-light-bookmark' for argument descriptions."
+  (interactive
+   (let* ((bmk  (bookmark-completing-read "Highlight bookmark"
+                                          nil
+                                          (bmkp-this-buffer-alist-only)
+                                          nil
+                                          nil
+                                          'USE-NIL-ALIST-P))
+          (sty  (and current-prefix-arg  (or (consp current-prefix-arg)
+                                             (<= (prefix-numeric-value current-prefix-arg) 0))
+                     (cdr (assoc (let ((completion-ignore-case  t))
+                                   (completing-read
+                                    "Style: " bmkp-light-styles-alist nil t nil nil
+                                    (and (bmkp-lighting-style bmk)
+                                         (format "%s" (car (rassq (bmkp-lighting-style bmk)
+                                                                  bmkp-light-styles-alist))))))
+                                 bmkp-light-styles-alist))))
+          (fac  (and current-prefix-arg  (or (consp current-prefix-arg)
+                                             (natnump (prefix-numeric-value current-prefix-arg)))
+                     (not (member sty '(lfringe rfringe none))) ; No face possible for these.
+                     (condition-case nil ; Emacs 22+ accepts a default.
+                         (read-face-name "Face: " (format "%S" (bmkp-lighting-face  bmk)))
+                       (wrong-number-of-arguments (read-face-name "Face: "))))))
+     (list bmk sty fac 'MSG)))
+  (bmkp-light-bookmark bookmark style face msgp))
+
+;;;###autoload (autoload 'bmkp-light-bookmarks "bookmark+")
+(defun bmkp-light-bookmarks (&optional alist overlays-symbols msgp) ; `C-x p H'
+  "Highlight bookmarks.
+A prefix argument determines which bookmarks to highlight:
+ none    - Current buffer, all bookmarks.
+ = 0     - Current buffer, highlighted bookmarks only (rehighlight).
+ > 0     - Current buffer, autonamed bookmarks only.
+ < 0     - Current buffer, non-autonamed bookmarks only.
+ C-u     - All buffers (all bookmarks) - after confirmation.
+ C-u C-u - Navlist (all bookmarks).
+
+Non-interactively, ALIST is the alist of bookmarks to highlight.
+It must be provided: if nil then do not highlight any bookmarks."
+  (interactive
+   (list (cond ((not current-prefix-arg)     (bmkp-this-buffer-alist-only))
+               ((consp current-prefix-arg)   (if (> (prefix-numeric-value current-prefix-arg) 4)
+                                                 bmkp-nav-alist
+                                               (unless (y-or-n-p
+                                                        "Confirm highlighting bookmarks in ALL buffers ")
+                                                 (error "Canceled highlighting"))
+                                               (bmkp-specific-buffers-alist-only
+                                                (mapcar #'buffer-name (buffer-list)))))
+               ((> current-prefix-arg 0)     (bmkp-autonamed-this-buffer-alist-only))
+               ((< current-prefix-arg 0)     (bmkp-remove-if #'bmkp-autonamed-bookmark-p
+                                                             (bmkp-this-buffer-alist-only)))
+               ((= current-prefix-arg 0)     (bmkp-this-buffer-lighted-alist-only)))
+         (cond ((or (not current-prefix-arg)  (consp current-prefix-arg))
+                '(bmkp-autonamed-overlays bmkp-non-autonamed-overlays))
+               ((natnump current-prefix-arg) '(bmkp-autonamed-overlays))
+               (current-prefix-arg           '(bmkp-non-autonamed-overlays)))
+         'MSG))
+  (unless overlays-symbols
+    (setq overlays-symbols  '(bmkp-autonamed-overlays bmkp-non-autonamed-overlays)))
+  (let ((bmkp-use-region  nil)          ; Inhibit region handling.
+        (total            0)
+        (nb-auto          0)
+        (nb-non-auto      0)
+        (new-auto         0)
+        (new-non-auto     0)
+        (nb-lit           (bmkp-number-lighted))
+        bmk bmk-name autonamedp face style pos buf bmk-ov passes-when-p)
+    (catch 'bmkp-light-bookmarks
+      (dolist (bookmark  alist)
+        (setq bmk            (bmkp-get-bookmark bookmark 'NOERROR) ; Should be a no-op.
+              bmk-name       (and bmk  (bmkp-bookmark-name-from-record bmk))
+              autonamedp     (and bmk  (bmkp-autonamed-bookmark-p bmk-name))
+              face           (and bmk  (bmkp-light-face bmk))
+              style          (and bmk  (bmkp-light-style bmk))
+              bmk-ov         (bmkp-overlay-of-bookmark bmk)
+              passes-when-p  (and bmk  (or bmk-ov ; Always highlight if already highlighted.
+                                           (bmkp-light-when bmk))))
+        (when (and bmk  passes-when-p)  ; Skip bad bookmark and respect `:when' (unless highlighted).
+          (setq pos  (bookmark-get-position bmk)
+                buf  (bmkp-get-buffer-name bmk))
+          (save-excursion
+            ;; An alternative here would be to call the handler and let it do the highlighting.
+            ;; In that case, we would need at least to bind the display function to nil while
+            ;; handling, so we don't also do the jump.  In particular, we don't want to pop to
+            ;; the bookmark in a new window or frame.
+            ;; Calling the handler would be good for some cases, such as Info, where the
+            ;; highlighting is not really specific to the buffer but to a narrowed part of it.
+            ;;
+            ;; (let ((bmkp-jump-display-function  nil)) (bookmark-handle-bookmark bmk))
+            ;;
+            ;; But calling the handler is in general the wrong thing.  We don't want highlighting
+            ;; all Dired bookmarks in a given directory to also do all the file marking and
+            ;; subdir hiding associated with each of the bookmarks.  So we do just the
+            ;; highlighting, no handling, putting the code in side `with-current-buffer'.
+            (with-current-buffer (or (and buf  (get-buffer buf))
+                                     (current-buffer))
+              (when (and pos  (< pos (point-max)))
+                (dolist (ov-symb  overlays-symbols)
+                  (when (or (and (eq 'bmkp-autonamed-overlays     ov-symb)  autonamedp)
+                            (and (eq 'bmkp-non-autonamed-overlays ov-symb)  (not autonamedp)))
+                    (let ((ov  (bmkp-make/move-overlay-of-style style pos autonamedp bmk bmk-ov)))
+                      (when ov          ; nil means `none' style.
+                        (add-to-list ov-symb ov)
+                        (when (eq 'bmkp-autonamed-overlays ov-symb)
+                          (unless bmk-ov (setq new-auto  (1+ new-auto)))
+                          (setq nb-auto  (1+ nb-auto)))
+                        (when (eq 'bmkp-non-autonamed-overlays ov-symb)
+                          (unless bmk-ov (setq new-non-auto  (1+ new-non-auto)))
+                          (setq nb-non-auto  (1+ nb-non-auto)))
+                        (when (and (not bmk-ov)  (> (setq nb-lit  (1+ nb-lit)) bmkp-light-threshold))
+                          (setq nb-lit  (1- nb-lit))
+                          (throw 'bmkp-light-bookmarks bmk))
+                        (setq total  (1+ total))
+                        (overlay-put ov 'priority ; > ediff's 100+, < isearch-overlay's 1001.
+                                     (or (cdr (assoc ov-symb bmkp-light-priorities))
+                                         (apply #'min (mapcar #'cdr bmkp-light-priorities))))
+                        (unless (memq style '(lfringe rfringe none)) (overlay-put ov 'face face))
+                        (overlay-put ov 'evaporate  t)
+                        (overlay-put ov 'category  'bookmark-plus)
+                        (overlay-put ov 'bookmark  bmk))))))))))) ; Use full bookmark - name can change.
+    (when msgp (message "%s New: %d auto + %d other,  Total: %d auto + %d other = %d"
+                        (if (consp current-prefix-arg)
+                            (if (> (prefix-numeric-value current-prefix-arg) 4)
+                                "[Navlist]"
+                              "[All buffers]")
+                          "[This buffer]")
+                        new-auto new-non-auto nb-auto nb-non-auto total))))
+
+;;;###autoload (autoload 'bmkp-light-navlist-bookmarks "bookmark+")
+(defun bmkp-light-navlist-bookmarks (&optional overlays-symbols msgp) ; Not bound
+  "Highlight bookmarks in the navigation list.
+No prefix arg:   all bookmarks.
+Prefix arg >= 0: autonamed bookmarks only.
+Prefix arg < 0:  non-autonamed bookmarks only."
+  (interactive
+   (list (cond ((not current-prefix-arg) '(bmkp-autonamed-overlays bmkp-non-autonamed-overlays))
+               ((natnump (prefix-numeric-value current-prefix-arg)) '(bmkp-autonamed-overlays))
+               (current-prefix-arg '(bmkp-non-autonamed-overlays)))
+         'MSG))
+  (bmkp-light-bookmarks bmkp-nav-alist overlays-symbols msgp))
+
+;;;###autoload (autoload 'bmkp-light-this-buffer "bookmark+")
+(defun bmkp-light-this-buffer (&optional overlays-symbols msgp) ; Not bound
+  "Highlight bookmarks in the current buffer.
+No prefix arg:   all bookmarks.
+Prefix arg >= 0: autonamed bookmarks only.
+Prefix arg < 0:  non-autonamed bookmarks only."
+  (interactive
+   (list (cond ((not current-prefix-arg) '(bmkp-autonamed-overlays bmkp-non-autonamed-overlays))
+               ((natnump (prefix-numeric-value current-prefix-arg)) '(bmkp-autonamed-overlays))
+               (current-prefix-arg '(bmkp-non-autonamed-overlays)))
+         'MSG))
+  (bmkp-light-bookmarks (bmkp-this-buffer-alist-only) overlays-symbols msgp))
+
+;;;###autoload (autoload 'bmkp-light-bookmarks-in-region "bookmark+")
+(defun bmkp-light-bookmarks-in-region (start end &optional overlays-symbols msgp) ; Not bound
+  "Highlight bookmarks in the region.
+No prefix arg:   all bookmarks.
+Prefix arg >= 0: autonamed bookmarks only.
+Prefix arg < 0:  non-autonamed bookmarks only."
+  (interactive
+   (list (region-beginning)
+         (region-end)
+         (cond ((not current-prefix-arg) '(bmkp-autonamed-overlays bmkp-non-autonamed-overlays))
+               ((natnump (prefix-numeric-value current-prefix-arg)) '(bmkp-autonamed-overlays))
+               (current-prefix-arg '(bmkp-non-autonamed-overlays)))
+         'MSG))
+  (bmkp-light-bookmarks (bmkp-remove-if-not (lambda (bmk) (let ((pos  (bookmark-get-position bmk)))
+                                                            (and (>= pos start)  (<= pos end))))
+                                            (bmkp-this-buffer-alist-only))
+                        overlays-symbols msgp))
+
+;;;###autoload (autoload 'bmkp-light-autonamed-this-buffer "bookmark+")
+(defun bmkp-light-autonamed-this-buffer (&optional msgp) ; Not bound
+  "Highlight all autonamed bookmarks."
+  (interactive (list 'MSG))
+  (bmkp-light-bookmarks (bmkp-autonamed-this-buffer-alist-only) '(bmkp-autonamed-overlays) msgp))
+
+;;;###autoload (autoload 'bmkp-light-non-autonamed-this-buffer "bookmark+")
+(defun bmkp-light-non-autonamed-this-buffer (&optional msgp) ; Not bound
+  "Highlight all non-autonamed bookmarks."
+  (interactive (list 'MSG))
+  (bmkp-light-bookmarks (bmkp-remove-if #'bmkp-autonamed-bookmark-p (bmkp-this-buffer-alist-only))
+                        '(bmkp-non-autonamed-overlays) msgp))
+
+;;;###autoload (autoload 'bmkp-cycle-lighted-this-buffer "bookmark+")
+(defun bmkp-cycle-lighted-this-buffer (increment &optional other-window startoverp) ; Not bound
+  "Cycle through highlighted bookmarks in this buffer by INCREMENT.
+Positive INCREMENT cycles forward.  Negative INCREMENT cycles backward.
+Interactively, the prefix arg determines INCREMENT:
+ Plain `C-u': 1
+ otherwise: the numeric prefix arg value
+
+To change the sort order, you can filter the `*Bookmark List*' to show
+only highlighted bookmarks for this buffer, sort the bookmarks there,
+and use `\\[bmkp-choose-navlist-from-bookmark-list]', choosing `CURRENT *Bookmark List*' as the
+navigation list.
+
+Then you can cycle the bookmarks using `bookmark-cycle'
+\(`\\[bmkp-next-bookmark-repeat]' etc.), instead of `bookmark-cycle-lighted-this-buffer'.
+
+In Lisp code:
+ Non-nil OTHER-WINDOW means jump to the bookmark in another window.
+ Non-nil STARTOVERP means reset `bmkp-current-nav-bookmark' to the
+ first bookmark in the navlist."
+  (interactive (let ((startovr  (consp current-prefix-arg)))
+                 (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) nil startovr)))
+  (bookmark-maybe-load-default-file)
+  (let ((bmkp-sort-comparer  bmkp-this-file/buffer-cycle-sort-comparer))
+    (setq bmkp-nav-alist  (bmkp-sort-omit (bmkp-this-buffer-lighted-alist-only))))
+  (unless bmkp-nav-alist (error "No lighted bookmarks for cycling"))
+  (unless (and bmkp-current-nav-bookmark
+               (not startoverp)
+               (bmkp-get-bookmark bmkp-current-nav-bookmark 'NOERROR)
+               (bmkp-this-buffer-p bmkp-current-nav-bookmark)) ; Exclude desktops etc.
+    (setq bmkp-current-nav-bookmark  (car bmkp-nav-alist)))
+  (if (bmkp-cycle-1 increment other-window startoverp)
+      (unless (or (bmkp-sequence-bookmark-p bmkp-current-nav-bookmark)
+                  (bmkp-function-bookmark-p bmkp-current-nav-bookmark))
+        (message "Position: %9d, Bookmark: `%s'" (point) (bmkp-bookmark-name-from-record
+                                                          bmkp-current-nav-bookmark)))
+    (message "Invalid bookmark: `%s'" (bmkp-bookmark-name-from-record bmkp-current-nav-bookmark))))
+
+;;;###autoload (autoload 'bmkp-cycle-lighted-this-buffer-other-window "bookmark+")
+(defun bmkp-cycle-lighted-this-buffer-other-window (increment &optional startoverp) ; Not bound
+  "Same as `bmkp-cycle-lighted-this-buffer' but uses another window."
+  (interactive (let ((startovr  (consp current-prefix-arg)))
+                 (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr)))
+  (bmkp-cycle-lighted-this-buffer increment 'OTHER-WINDOW startoverp))
+
+;;;###autoload (autoload 'bmkp-next-lighted-this-buffer "bookmark+")
+(defun bmkp-next-lighted-this-buffer (n &optional startoverp) ; Repeatable key (e.g. `S-f2'), not bound
+  "Jump to the Nth-next highlighted bookmark in the current buffer.
+N defaults to 1, meaning the next one.
+Plain `C-u' means start over at the first one.
+See also `bmkp-cycle-lighted-this-buffer'."
+  (interactive (let ((startovr  (consp current-prefix-arg)))
+                 (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr)))
+  (bmkp-cycle-lighted-this-buffer n nil startoverp))
+
+;;;###autoload (autoload 'bmkp-previous-lighted-this-buffer "bookmark+")
+(defun bmkp-previous-lighted-this-buffer (n &optional startoverp) ; Repeatable key (e.g. `f2'), not bound
+  "Jump to the Nth-previous highlighted bookmark in the current buffer.
+See `bmkp-next-lighted-this-buffer'."
+  (interactive (let ((startovr  (consp current-prefix-arg)))
+                 (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr)))
+  (bmkp-cycle-lighted-this-buffer (- n) nil startoverp))
+
+;;;###autoload (autoload 'bmkp-next-lighted-this-buffer-repeat "bookmark+")
+(defun bmkp-next-lighted-this-buffer-repeat (arg) ; `C-x p C-down'
+  "Jump to the Nth next highlighted bookmark in the current buffer.
+This is a repeatable version of `bmkp-next-bookmark-this-buffer'.
+N defaults to 1, meaning the next one.
+Plain `C-u' means start over at the first one (and no repeat)."
+  (interactive "P")
+  (require 'repeat)
+  (bmkp-repeat-command 'bmkp-next-lighted-this-buffer))
+
+;;;###autoload (autoload 'bmkp-previous-lighted-this-buffer-repeat "bookmark+")
+(defun bmkp-previous-lighted-this-buffer-repeat (arg) ; `C-x p C-up'
+  "Jump to the Nth previous highlighted bookmark in the current buffer.
+See `bmkp-next-lighted-this-buffer-repeat'."
+  (interactive "P")
+  (require 'repeat)
+  (bmkp-repeat-command 'bmkp-previous-lighted-this-buffer))
+
+;;;###autoload (autoload 'bmkp-describe-bookmark-lighted-here "bookmark+")
+(defun bmkp-describe-bookmark-lighted-here (&optional position defn) ; `C-x p ?'
+  "Describe a highlighted bookmark at point or the same line.
+If there is more than one highlighted bookmark present then which one
+is described is undefined.  When multiple highlighted bookmarks are
+present you might want to use `\\[bmkp-bookmarks-lighted-at-point]' to see the names of all of the
+bookmarks at point, and then use `\\[bmkp-describe-bookmark]' to describe one of them.
+
+When called from Lisp:
+ * Use POSITION, not point.
+ * DEFN corresponds to the prefix arg: non-nil means show show the
+   internal definition of the bookmark."
+  (interactive (list (point) current-prefix-arg))
+  (let ((bmk  (or (bmkp-a-bookmark-lighted-at-pos position 'FULL)
+                  (bmkp-a-bookmark-lighted-on-this-line 'FULL))))
+    (unless bmk (error "No highlighted bookmark on this line"))
+    (bmkp-describe-bookmark bmk defn)))
+
+
+;;(@* "Other Functions")
+;;  *** Other Functions ***
+
+(defun bmkp-light-face (bookmark)
+  "Return the face to use to highlight BOOKMARK.
+BOOKMARK is a bookmark name or a bookmark record.
+Returns:
+ nil if BOOKMARK is not a valid bookmark;
+ the `:face', if any, specified by BOOKMARK's `lighting' entry;
+ `bmkp-light-autonamed-region' if an autonamed region bookmark;
+ `bmkp-light-non-autonamed-region' if a non-autonamed region bookmark;
+ `bmkp-light-autonamed' if an autonamed non-region bookmark;
+ `bmkp-light-non-autonamed' otherwise."
+  (setq bookmark  (bmkp-get-bookmark bookmark 'NOERROR))
+  (or (bmkp-lighting-face bookmark)
+      (and bookmark  (if (bmkp-region-bookmark-p bookmark)
+                         (if (bmkp-autonamed-bookmark-p bookmark)
+                             'bmkp-light-autonamed-region
+                           'bmkp-light-non-autonamed-region)
+                       (if (bmkp-autonamed-bookmark-p bookmark)
+                           'bmkp-light-autonamed
+                         'bmkp-light-non-autonamed)))))
+
+(defun bmkp-light-style (bookmark)
+  "Return the style to use to highlight BOOKMARK.
+BOOKMARK is a bookmark name or a bookmark record.
+Returns:
+ * nil if BOOKMARK is not a valid bookmark;
+ * the `:style', if any, specified by BOOKMARK's `lighting' entry;
+ * the value of `bmkp-light-style-autonamed-region' if autonamed and
+     recording a region
+ * the value of `bmkp-light-style-non-autonamed-region' if autonamed
+     and recording a region
+ * the value of `bmkp-light-style-autonamed' if autonamed and not
+     recording a region
+ * the value of `bmkp-light-style-non-autonamed-region' if autonamed
+     and not recording a region"
+  (setq bookmark  (bmkp-get-bookmark bookmark 'NOERROR))
+  (or (bmkp-lighting-style bookmark)
+      (and bookmark  (if (bmkp-region-bookmark-p bookmark)
+                         (if (bmkp-autonamed-bookmark-p bookmark)
+                             bmkp-light-style-autonamed-region
+                           bmkp-light-style-non-autonamed-region)
+                       (if (bmkp-autonamed-bookmark-p bookmark)
+                           bmkp-light-style-autonamed
+                         bmkp-light-style-non-autonamed)))))
+
+(defun bmkp-light-when (bookmark)
+  "Return non-nil if BOOKMARK should be highlighted.
+BOOKMARK's  `:when' condition is used to determine this.
+BOOKMARK is a bookmark name or a bookmark record."
+  (setq bookmark  (bmkp-get-bookmark bookmark 'NOERROR))
+  (let ((this-bookmark       bookmark)
+        (this-bookmark-name  (bmkp-bookmark-name-from-record bookmark))
+        (when-sexp           (bmkp-lighting-when bookmark)))
+    (not (eq :no-light (eval when-sexp)))))
+
+(defun bmkp-lighting-face (bookmark)
+  "`:face' specified by BOOKMARK's `lighting', or nil if no `:face' entry.
+BOOKMARK is a bookmark name or a bookmark record.
+
+The `:face' entry is the face (a symbol) used to highlight BOOKMARK.
+Alternatively, it can be `auto' or nil, which both mean the same as
+having no `:face' entry: do not override automatic face choice."
+  (bmkp-lighting-attribute bookmark :face))
+
+(defun bmkp-lighting-style (bookmark)
+  "`:style' specified by BOOKMARK's `lighting', or nil if no `:style' entry.
+BOOKMARK is a bookmark name or a bookmark record.
+
+The `:style' entry is the style used to highlight BOOKMARK.
+It is a value acceptable for `bmkp-light-style-non-autonamed'.
+Alternatively, it can be `auto' or nil, which both mean the same as
+having no `:style' entry: do not override automatic style choice."
+  (bmkp-lighting-attribute bookmark :style))
+
+(defun bmkp-lighting-when (bookmark)
+  "`:when' specified by BOOKMARK's `lighting', or nil if no `:when' entry.
+BOOKMARK is a bookmark name or a bookmark record.
+
+The `:when' entry is a sexp that is eval'd when you try to highlight
+BOOKMARK.  If the result is the symbol `:no-light', then do not
+highlight.  Otherwise, highlight.  (Note that highlighting happens if
+the value is nil or there is no `:when' entry.)"
+  (bmkp-lighting-attribute bookmark :when))
+
+(defun bmkp-lighting-attribute (bookmark attribute)
+  "ATTRIBUTE specified by BOOKMARK's `lighting', or nil if no such attribute.
+BOOKMARK is a bookmark name or a bookmark record.
+ATTRIBUTE is `:style' or `:face'."
+  (setq bookmark  (bmkp-get-bookmark bookmark 'NOERROR))
+  (let* ((lighting  (and bookmark  (bmkp-get-lighting bookmark)))
+         (attr      (and (consp lighting)  (plist-get lighting attribute))))
+    (when (and (eq 'auto attr)  (not (eq :when attribute)))
+      (setq attr  nil))
+    attr))
+
+(defun bmkp-get-lighting (bookmark)
+  "Return the `lighting' property list for BOOKMARK.
+This is the cdr of the `lighting' entry (i.e. the rest of the entry,
+  with `lighting' removed).
+BOOKMARK is a bookmark name or a bookmark record."
+  (bookmark-prop-get bookmark 'lighting))
+
+(defun bmkp-bookmark-overlay-p (overlay)
+  "Return non-nil if OVERLAY is a bookmark overlay.
+The non-nil value returned is in fact the full bookmark."
+  (and (overlayp overlay)  (overlay-get overlay 'bookmark)))
+
+(defun bmkp-default-lighted ()
+  "Return a highlighted bookmark at point or on this line, or nil if none.
+For Emacs 23+, if there is a highlighted bookmark at point, return a
+ list of all such."
+  (or (if (> emacs-major-version 22) (bmkp-bookmarks-lighted-at-point) (bmkp-a-bookmark-lighted-at-pos))
+      (bmkp-a-bookmark-lighted-on-this-line)))
+
+(defun bmkp-a-bookmark-lighted-on-this-line (&optional fullp msgp)
+  "Return a bookmark highlighted on the current line or nil if none.
+The search for a highlighted bookmark moves left to bol from point,
+ then right to eol from point.
+Return the bookmark name or, if FULLP non-nil, the full bookmark data."
+  (let ((pos  (point))
+        (bol  (1+ (line-beginning-position)))
+        (eol  (1- (line-end-position)))
+        bmk)
+    (catch 'bmkp-a-bookmark-lighted-on-this-line
+      (while (>= pos bol)
+        (when (setq bmk  (bmkp-a-bookmark-lighted-at-pos pos))
+          (throw 'bmkp-a-bookmark-lighted-on-this-line bmk))
+        (setq pos  (1- pos)))
+      (while (<= pos eol)
+        (when (setq bmk  (bmkp-a-bookmark-lighted-at-pos pos))
+          (throw 'bmkp-a-bookmark-lighted-on-this-line bmk))
+        (setq pos  (1+ pos)))
+      nil)
+    (when (and bmk  fullp)  (setq bmk  (bmkp-get-bookmark bmk)))
+    bmk))
+
+(defun bmkp-a-bookmark-lighted-at-pos (&optional position fullp)
+  "Return a bookmark (in current bookmark list) highlighted at POSITION.
+Return nil if there is none such.
+POSITION defaults to point.
+Return the bookmark name or, if FULLP non-nil, the full bookmark data."
+  (unless position (setq position  (point)))
+  (let (bmk)
+    (catch 'bmkp-a-bookmark-lighted-at-pos
+      (dolist (ov  (overlays-at position))
+        (when (setq bmk  (overlay-get ov 'bookmark))
+          (throw 'bmkp-a-bookmark-lighted-at-pos bmk)))
+      nil)
+    (let ((b-in-list  (bmkp-get-bookmark-in-alist bmk 'NOERROR)))
+      (and b-in-list                    ; Must be in current bookmark list.
+           (if fullp b-in-list (bmkp-bookmark-name-from-record bmk))))))
+
+(defun bmkp-read-set-lighting-args (&optional default-style default-face default-when)
+  "Read args STYLE, FACE, and WHEN for commands that set `lighting' prop.
+Optional args are the default values (strings) for reading new values."
+  (let* ((icicle-unpropertize-completion-result-flag  t)
+         (style       (cdr (assoc (let ((completion-ignore-case  t))
+                                    (completing-read "Style: " bmkp-light-styles-alist
+                                                     nil t nil nil default-style))
+                                  bmkp-light-styles-alist)))
+         (face        (and (not (member style '(lfringe rfringe none))) ; No face possible for these.
+                           (y-or-n-p "Change face? ") ; Allow nil, for `auto'.
+                           (condition-case nil ; Emacs 22+ accepts a default.
+                               (read-face-name "Face: " default-face)
+                             (wrong-number-of-arguments (read-face-name "Face: ")))))
+         (when-cands  `(("auto" . nil)
+                        ("conditionally (read sexp)")
+                        ("never"  . :no-light)))
+         (when         (completing-read "When: " when-cands nil t nil nil
+                                        (if default-when "conditionally (read sexp)" "auto")))
+         (evald       (if (bmkp-string-match-p "^con" when)
+                          (read-from-minibuffer "Highlight when (sexp): " nil
+                                                (if (boundp 'pp-read-expression-map)
+                                                    pp-read-expression-map
+                                                  read-expression-map)
+                                                t 'read-expression-history default-when)
+                        (cdr (assoc when when-cands)))))
+    (list style face evald)))
+
+(defun bmkp-lighted-alist-only ()
+  "`bookmark-alist', with only highlighted bookmarks.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not (lambda (bmk) (bmkp-lighted-p bmk)) bookmark-alist))
+
+(defun bmkp-this-buffer-lighted-alist-only ()
+  "`bookmark-alist', with only highlighted bookmarks for the current buffer.
+A new list is returned (no side effects)."
+  (bookmark-maybe-load-default-file)
+  (bmkp-remove-if-not (lambda (bmk) (and (bmkp-this-buffer-p bmk)  (bmkp-lighted-p bmk)))
+                      bookmark-alist))
+
+(defun bmkp-number-lighted (&optional overlays-symbols)
+  "Number of bookmarks highlighted."
+  (unless overlays-symbols
+    (setq overlays-symbols  '(bmkp-autonamed-overlays bmkp-non-autonamed-overlays)))
+  (let ((count  0))
+    (dolist (ov-symb  overlays-symbols)
+      (dolist (ov  (symbol-value ov-symb)) (when (overlay-buffer ov) (setq count  (1+ count)))))
+    count))
+
+(defalias 'bmkp-lighted-p 'bmkp-overlay-of-bookmark)
+(defun bmkp-overlay-of-bookmark (bookmark &optional overlays)
+  "Return the overlay for BOOKMARK in OVERLAYS, or nil if none.
+BOOKMARK is a bookmark name or a bookmark record.
+Optional arg OVERLAYS is the list of overlays to check.
+If nil, check overlays for both autonamed and non-autonamed bookmarks."
+  (setq bookmark  (bmkp-get-bookmark bookmark 'NOERROR))
+  (and bookmark                         ; Return nil for no such bookmark.
+       (catch 'bmkp-overlay-of-bookmark
+         (dolist (ov  (if overlays
+                          (apply #'append (mapcar #'symbol-value overlays))
+                        (append bmkp-autonamed-overlays bmkp-non-autonamed-overlays)))
+           (when (and (overlay-buffer ov)  (eq bookmark (overlay-get ov 'bookmark)))
+             (throw 'bmkp-overlay-of-bookmark ov)))
+         nil)))
+
+(defun bmkp-make/move-overlay-of-style (style pos autonamedp bookmark &optional overlay)
+  "Return a bookmark overlay of STYLE at position POS for BOOKMARK.
+AUTONAMEDP non-nil means the bookmark is autonamed.
+Regardless of STYLE, set `help-echo' to the bookmark description.
+If OVERLAY is non-nil:
+  Then it is the overlay to use - change to STYLE and return overlay.
+  Otherwise, create a new overlay and return it.
+If STYLE is `none' then:
+  If OVERLAY is non-nil, delete it and return nil."
+  (let ((ov  overlay))
+    (when (and (< emacs-major-version 22)  (not (rassq style bmkp-light-styles-alist)))
+      (message "Fringe styles not supported before Emacs 22 - changing to `line' style")
+      (setq style 'line))
+    (case style
+      (region        (and (bmkp-region-bookmark-p bookmark)
+                          (let ((end  (bmkp-get-end-position bookmark)))
+                            (if (not ov)
+                                (setq ov  (make-overlay pos end nil 'FRONT-ADVANCE))
+                              (move-overlay ov pos end)))))
+      (line          (if (not ov)
+                         (setq ov  (save-excursion
+                                     (make-overlay
+                                      (progn (goto-char pos) (line-beginning-position 1))
+                                      (progn (goto-char pos) (line-beginning-position 2))
+                                      nil
+                                      'FRONT-ADVANCE)))
+                       (overlay-put ov 'before-string nil) ; Remove any fringe highlighting.
+                       (save-excursion
+                         (move-overlay ov
+                                       (progn (goto-char pos) (line-beginning-position 1))
+                                       (progn (goto-char pos) (line-beginning-position 2))))))
+      (lfringe       (setq ov  (bmkp-make/move-fringe 'left  pos autonamedp ov)))
+      (rfringe       (setq ov  (bmkp-make/move-fringe 'right pos autonamedp ov)))
+      (line+lfringe  (setq ov  (bmkp-make/move-fringe 'left  pos autonamedp ov 'LINEP)))
+      (line+rfringe  (setq ov  (bmkp-make/move-fringe 'right pos autonamedp ov 'LINEP)))
+      (bol           (if (not ov)
+                         (setq ov  (save-excursion (goto-char pos)
+                                                   (make-overlay (line-beginning-position)
+                                                                 (1+ (line-beginning-position))
+                                                                 nil
+                                                                 'FRONT-ADVANCE)))
+                       (overlay-put ov 'before-string nil) ; Remove any fringe highlighting.
+                       (save-excursion (goto-char pos)
+                                       (move-overlay ov (line-beginning-position)
+                                                     (1+ (line-beginning-position))))))
+      (point         (if (not ov)
+                         (setq ov  (make-overlay pos (1+ pos) nil 'FRONT-ADVANCE))
+                       (overlay-put ov 'before-string nil) ; Remove any fringe highlighting.
+                       (move-overlay ov pos (1+ pos))))
+      (none          (when ov (delete-overlay ov))  (setq ov nil)))
+
+    ;; Emacs bug # prevents making use of a face in a `help-echo' tooltip.
+    ;; (when ov (overlay-put ov 'help-echo (bmkp-propertize (funcall bmkp-tooltip-content-function bookmark)
+    ;;                                                      'face 'bmkp-tooltip-content-face)))
+    (when ov (overlay-put ov 'help-echo (funcall bmkp-tooltip-content-function bookmark)))
+    ov))
+
+;; Not used for Emacs 20-21.
+(defun bmkp-make/move-fringe (side pos autonamedp &optional overlay linep)
+  "Return an overlay that uses the fringe.
+If SIDE is `right' then use the right fringe, otherwise left.
+POS is the overlay position.
+AUTONAMEDP: non-nil means use face `bmkp-light-fringe-autonamed'.
+            nil means use face `bmkp-light-fringe-non-autonamed'.
+If OVERLAY is non-nil it is the overlay to use.
+ Otherwise, create a new overlay.
+Non-nil LINEP means also highlight the line containing POS."
+  (unless (> emacs-major-version 21) (error "Fringe styles not supported before Emacs 22"))
+  (let ((ov  overlay))
+    (if ov
+        (save-excursion (move-overlay overlay (progn (goto-char pos)
+                                                     (goto-char (line-beginning-position)))
+                                      (1+ (point))))
+      (setq ov  (save-excursion (make-overlay (progn (goto-char pos)
+                                                     (goto-char (line-beginning-position)))
+                                              (1+ (point))
+                                              nil
+                                              'FRONT-ADVANCE))))
+    (overlay-put ov 'before-string (bmkp-fringe-string side autonamedp))
+    (if linep
+        (move-overlay ov (save-excursion (goto-char pos) (line-beginning-position 1))
+                      (save-excursion (goto-char pos) (line-beginning-position 2)))
+      (overlay-put ov 'face nil))       ; Remove any non-fringe highlighting.
+    ov))
+
+;; Not used for Emacs 20-21.
+(defun bmkp-fringe-string (side autonamedp)
+  "Return a fringe string for a bookmark overlay.
+If SIDE is `right' then use the right fringe, otherwise left.
+AUTONAMEDP: non-nil means use face `bmkp-light-fringe-autonamed'.
+            nil means use face `bmkp-light-fringe-non-autonamed'."
+  (unless (> emacs-major-version 21) (error "Fringe styles not supported before Emacs 22"))
+  (let ((fringe-string  (copy-sequence (if autonamedp "*AUTO*" "*NONAUTO*"))))
+    (put-text-property 0         (length fringe-string)
+                       'display  (if (eq side 'right)
+                                     (list 'right-fringe
+                                           bmkp-light-right-fringe-bitmap
+                                           (if autonamedp
+                                               'bmkp-light-fringe-autonamed
+                                             'bmkp-light-fringe-non-autonamed))
+                                   (list 'left-fringe
+                                         bmkp-light-left-fringe-bitmap
+                                         (if autonamedp
+                                             'bmkp-light-fringe-autonamed
+                                           'bmkp-light-fringe-non-autonamed)))
+                       fringe-string)
+    fringe-string))
+
+;; This is also in `bookmark+-bmu.el', since `bookmark+-lit.el' is loaded first but is optional.
+;;
+(if (fboundp 'pop-to-buffer-same-window)
+    (defalias 'bmkp--pop-to-buffer-same-window 'pop-to-buffer-same-window)
+  (defalias 'bmkp--pop-to-buffer-same-window 'switch-to-buffer))
+
+
+;;;;;;;;;;;;;;;;;;;
+
+(provide 'bookmark+-lit)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; bookmark+-lit.el ends here
diff --git a/lisp/bookmark+-mac.el b/lisp/bookmark+-mac.el
new file mode 100644 (file)
index 0000000..7b6745e
--- /dev/null
@@ -0,0 +1,558 @@
+;;; bookmark+-mac.el --- Macros for Bookmark+.
+;;
+;; Filename: bookmark+-mac.el
+;; Description: Macros for Bookmark+.
+;; Author: Drew Adams
+;; Maintainer: Drew Adams
+;; Copyright (C) 2000-2022, Drew Adams, all rights reserved.
+;; Created: Sun Aug 15 11:12:30 2010 (-0700)
+;; Last-Updated: Fri Jan 14 12:34:20 2022 (-0800)
+;;           By: dradams
+;;     Update #: 223
+;; URL: https://www.emacswiki.org/emacs/download/bookmark%2b-mac.el
+;; Doc URL: https://www.emacswiki.org/emacs/BookmarkPlus
+;; Keywords: bookmarks, bookmark+, placeholders, annotations, search, info, url, eww, w3m, gnus
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x, 24.x, 25.x, 26.x
+;;
+;; Features that might be required by this library:
+;;
+;;   None
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;    Macros for Bookmark+.
+;;
+;;    The Bookmark+ libraries are these:
+;;
+;;    `bookmark+.el'     - main (driver) library
+;;    `bookmark+-mac.el' - Lisp macros (this file)
+;;    `bookmark+-bmu.el' - code for the `*Bookmark List*' (bmenu)
+;;    `bookmark+-1.el'   - other (non-bmenu) required code
+;;    `bookmark+-lit.el' - (optional) code for highlighting bookmarks
+;;    `bookmark+-key.el' - key and menu bindings
+;;
+;;    `bookmark+-doc.el' - documentation (comment-only file)
+;;    `bookmark+-chg.el' - change log (comment-only file)
+;;
+;;    The documentation (in `bookmark+-doc.el') includes how to
+;;    byte-compile and install Bookmark+.  The documentation is also
+;;    available in these ways:
+;;
+;;    1. From the bookmark list (`C-x r l'):
+;;       Use `?' to show the current bookmark-list status and general
+;;       help, then click link `Doc in Commentary' or link `Doc on the
+;;       Web'.
+;;
+;;    2. From the Emacs-Wiki Web site:
+;;       https://www.emacswiki.org/emacs/BookmarkPlus.
+;;
+;;    3. From the Bookmark+ group customization buffer:
+;;       `M-x customize-group bookmark-plus', then click link
+;;       `Commentary'.
+;;
+;;    (The commentary links in #1 and #3 work only if you have library
+;;    `bookmark+-doc.el' in your `load-path'.)
+;;
+;;
+;;    ****** NOTE ******
+;;
+;;      WHENEVER you update Bookmark+ (i.e., download new versions of
+;;      Bookmark+ source files), I recommend that you do the
+;;      following:
+;;
+;;      1. Delete ALL existing BYTE-COMPILED Bookmark+ files
+;;         (bookmark+*.elc).
+;;      2. Load Bookmark+ (`load-library' or `require').
+;;      3. Byte-compile the source files.
+;;
+;;      In particular, ALWAYS LOAD `bookmark+-mac.el' (not
+;;      `bookmark+-mac.elc') BEFORE YOU BYTE-COMPILE new versions of
+;;      the files, in case there have been any changes to Lisp macros
+;;      (in `bookmark+-mac.el').
+;;
+;;      (This is standard procedure for Lisp: code that depends on
+;;      macros needs to be byte-compiled anew after loading the
+;;      updated macros.)
+;;
+;;    ******************
+ 
+;;(@> "Index")
+;;
+;;  If you have library `linkd.el' and Emacs 22 or later, load
+;;  `linkd.el' and turn on `linkd-mode' now.  It lets you easily
+;;  navigate around the sections of this doc.  Linkd mode will
+;;  highlight this Index, as well as the cross-references and section
+;;  headings throughout this file.  You can get `linkd.el' here:
+;;  https://www.emacswiki.org/emacs/download/linkd.el.
+;;
+;;  (@> "Things Defined Here")
+;;  (@> "Functions")
+;;  (@> "Macros")
+ 
+;;(@* "Things Defined Here")
+;;
+;;  Things Defined Here
+;;  -------------------
+;;
+;;  Macros defined here:
+;;
+;;    `bmkp-define-cycle-command', `bmkp-define-history-variables',
+;;    `bmkp-define-next+prev-cycle-commands',
+;;    `bmkp-define-show-only-command', `bmkp-define-sort-command',
+;;    `bmkp-define-file-sort-predicate', `bmkp-menu-bar-make-toggle',
+;;    `bmkp-with-bookmark-dir', `bmkp-with-help-window',
+;;    `bmkp-with-output-to-plain-temp-buffer'.
+;;
+;;  Non-interactive functions defined here:
+;;
+;;    `bmkp-bookmark-data-from-record',
+;;    `bmkp-bookmark-name-from-record',
+;;    `bmkp-replace-regexp-in-string', `bmkp-types-alist',
+;;    `bookmark-name-from-full-record', `bookmark-name-from-record'.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 3, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;
+
+(require 'bookmark)
+;; bookmark-bmenu-bookmark, bookmark-bmenu-ensure-position,
+;; bookmark-bmenu-surreptitiously-rebuild-list, bmkp-get-bookmark,
+;; bookmark-get-filename
+
+ 
+;;(@* "Functions")
+
+;; Some general Renamings.
+;;
+;; 1. Fix incompatibility introduced by gratuitous Emacs name change.
+;;
+(cond ((and (fboundp 'bookmark-name-from-record) (not (fboundp 'bookmark-name-from-full-record)))
+       (defalias 'bookmark-name-from-full-record 'bookmark-name-from-record))
+      ((and (fboundp 'bookmark-name-from-full-record) (not (fboundp 'bookmark-name-from-record)))
+       (defalias 'bookmark-name-from-record 'bookmark-name-from-full-record)))
+
+;; 2. The vanilla name of the first is misleading, as it returns only the cdr of the record.
+;;    The second is for consistency.
+;;
+(defalias 'bmkp-bookmark-data-from-record 'bookmark-get-bookmark-record)
+(defalias 'bmkp-bookmark-name-from-record 'bookmark-name-from-full-record)
+
+
+;; (eval-when-compile (require 'bookmark+-bmu))
+;; bmkp-assoc-delete-all, bmkp-bmenu-barf-if-not-in-menu-list,
+;; bmkp-bmenu-goto-bookmark-named, bmkp-sort-orders-alist
+
+;; (eval-when-compile (require 'bookmark+-1))
+;; bmkp-file-bookmark-p, bmkp-float-time, bmkp-local-file-bookmark-p,
+;; bmkp-msg-about-sort-order, bmkp-reverse-sort-p, bmkp-sort-comparer
+
+
+;;; This is also defined in `bookmark+-bmu.el'.  It is used here to produce the code for
+;;; `bmkp-define-show-only-command' and `bmkp-define-sort-command'.
+;;;
+(defun bmkp-replace-regexp-in-string (regexp rep string &optional fixedcase literal subexp start)
+  "Replace all matches for REGEXP with REP in STRING and return STRING."
+  (if (fboundp 'replace-regexp-in-string) ; Emacs > 20.
+      (replace-regexp-in-string regexp rep string fixedcase literal subexp start)
+    (if (string-match regexp string) (replace-match rep nil nil string) string))) ; Emacs 20
+ 
+;;(@* "Macros")
+
+;;; Macros -----------------------------------------------------------
+
+;; Same as `icicle-with-help-window' in `icicles-mac.el'.
+;;;###autoload (autoload 'bmkp-with-help-window "bookmark+")
+(defmacro bmkp-with-help-window (buffer &rest body)
+  "`with-help-window', if available; else `with-output-to-temp-buffer'."
+  (if (fboundp 'with-help-window)
+      `(with-help-window ,buffer ,@body)
+    `(with-output-to-temp-buffer ,buffer ,@body)))
+
+(put 'bmkp-with-help-window 'common-lisp-indent-function '(4 &body))
+
+
+;;;###autoload (autoload 'bmkp-with-output-to-plain-temp-buffer "bookmark+")
+(defmacro bmkp-with-output-to-plain-temp-buffer (buf &rest body)
+  "Like `with-output-to-temp-buffer', but with no `*Help*' navigation stuff."
+  `(unwind-protect
+    (progn
+      (remove-hook 'temp-buffer-setup-hook 'help-mode-setup)
+      (remove-hook 'temp-buffer-show-hook  'help-mode-finish)
+      (with-output-to-temp-buffer ,buf ,@body))
+    (add-hook 'temp-buffer-setup-hook 'help-mode-setup)
+    (add-hook 'temp-buffer-show-hook  'help-mode-finish)))
+
+(put 'bmkp-with-output-to-plain-temp-buffer 'common-lisp-indent-function '(4 &body))
+
+
+;;;###autoload (autoload 'bmkp-define-cycle-command "bookmark+")
+(defmacro bmkp-define-cycle-command (type &optional otherp)
+  "Define a cycling command for bookmarks of type TYPE.
+Non-nil OTHERP means define a command that cycles in another window."
+  `(defun ,(intern (format "bmkp-cycle-%s%s" type (if otherp "-other-window" "")))
+    (increment &optional startoverp)
+    ,(if otherp
+         (format "Same as `bmkp-cycle-%s', but use other window." type)
+         (format "Cycle through %s bookmarks by INCREMENT (default: 1).
+Positive INCREMENT cycles forward.  Negative INCREMENT cycles backward.
+Interactively, the prefix arg determines INCREMENT:
+ Plain `C-u': 1
+ otherwise: the numeric prefix arg value
+
+Plain `C-u' also means start over at first bookmark.
+
+In Lisp code:
+ Non-nil STARTOVERP means reset `bmkp-current-nav-bookmark' to the
+ first bookmark in the navlist." type))
+    (interactive (let ((startovr  (consp current-prefix-arg)))
+                   (list (if startovr 1 (prefix-numeric-value current-prefix-arg))
+                         startovr)))
+    (let ((bmkp-nav-alist  (bmkp-sort-omit (,(intern (format "bmkp-%s-alist-only" type))))))
+      (bmkp-cycle increment ,otherp startoverp))))
+
+;;;###autoload (autoload 'bmkp-define-next+prev-cycle-commands "bookmark+")
+(defmacro bmkp-define-next+prev-cycle-commands (type &optional otherp)
+  "Define `next' and `previous' commands for bookmarks of type TYPE.
+Non-nil OTHERP means define a command that cycles in another window."
+  `(progn
+    ;; `next' command.
+    (defun ,(intern (format "bmkp-next-%s-bookmark%s" type (if otherp "-other-window" "")))
+        (n &optional startoverp)
+      ,(if otherp
+           (format "Same as `bmkp-next-%s-bookmark', but use other window." type)
+           (format "Jump to the Nth-next %s bookmark.
+N defaults to 1, meaning the next one.
+Plain `C-u' means start over at the first one.
+See also `bmkp-cycle-%s'." type type))
+      (interactive (let ((startovr  (consp current-prefix-arg)))
+                     (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr)))
+      (,(intern (format "bmkp-cycle-%s%s" type (if otherp "-other-window" ""))) n startoverp))
+
+    ;; `previous' command.
+    (defun ,(intern (format "bmkp-previous-%s-bookmark%s" type (if otherp "-other-window" "")))
+        (n &optional startoverp)
+      ,(if otherp
+           (format "Same as `bmkp-previous-%s-bookmark', but use other window." type)
+           (format "Jump to the Nth-previous %s bookmark.
+See `bmkp-next-%s-bookmark'." type type))
+      (interactive (let ((startovr  (consp current-prefix-arg)))
+                     (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr)))
+      (,(intern (format "bmkp-cycle-%s%s" type (if otherp "-other-window" "")))
+        (- n) startoverp))
+
+    ;; `next' repeating command.
+    (defun ,(intern (format "bmkp-next-%s-bookmark%s-repeat"
+                            type
+                            (if otherp "-other-window" "")))
+        (arg)
+      ,(if otherp
+           (format "Same as `bmkp-next-%s-bookmark-repeat', but use other window." type)
+           (format "Jump to the Nth-next %s bookmark.
+This is a repeatable version of `bmkp-next-%s-bookmark'.
+N defaults to 1, meaning the next one.
+Plain `C-u' means start over at the first one (and no repeat)." type type))
+      (interactive "P")
+      (require 'repeat)
+      (bmkp-repeat-command
+       ',(intern (format "bmkp-next-%s-bookmark%s" type (if otherp "-other-window" "")))))
+
+    ;; `previous repeating command.
+    (defun ,(intern (format "bmkp-previous-%s-bookmark%s-repeat"
+                            type
+                            (if otherp "-other-window" "")))
+        (arg)
+      ,(if otherp
+           (format "Same as `bmkp-previous-%s-bookmark-repeat', but use other window." type)
+           (format "Jump to the Nth-previous %s bookmark.
+See `bmkp-next-%s-bookmark-repeat'." type type))
+      (interactive "P")
+      (require 'repeat)
+      (bmkp-repeat-command
+       ',(intern (format "bmkp-previous-%s-bookmark%s" type (if otherp "-other-window" "")))))))
+
+;; We don't bother making this hygienic.  Presumably only the Bookmark+ code will call it.
+;;;###autoload (autoload 'bmkp-define-show-only-command "bookmark+")
+(defmacro bmkp-define-show-only-command (type doc-string filter-function)
+  "Define a command to show only bookmarks of TYPE in *Bookmark List*.
+TYPE is a short string or symbol describing the type of bookmarks.
+
+The new command is named `bmkp-bmenu-show-only-TYPED-bookmarks', where
+TYPED is TYPE, but with any spaces replaced by hyphens (`-').
+Example: `bmkp-bmenu-show-only-tagged-bookmarks', for TYPE `tagged'.
+
+DOC-STRING is the doc string of the new command.
+
+The command shows only the bookmarks allowed by FILTER-FUNCTION.
+
+In case of error, variables `bmkp-bmenu-filter-function',
+`bmkp-bmenu-title', and `bmkp-latest-bookmark-alist' are reset to
+their values before the command was invoked."
+  (unless (stringp type) (setq type  (symbol-name type)))
+  (let* ((type--   (bmkp-replace-regexp-in-string "\\s-+" "-" type))
+         (command  (intern (format "bmkp-bmenu-show-only-%s-bookmarks" type--))))
+    `(progn
+      (defun ,command ()
+        ,doc-string
+        (interactive)
+        (bmkp-bmenu-barf-if-not-in-menu-list)
+        (let ((orig-filter-fn      bmkp-bmenu-filter-function)
+              (orig-title          bmkp-bmenu-title)
+              (orig-latest-alist   bmkp-latest-bookmark-alist))
+          (condition-case err
+              (progn (setq bmkp-bmenu-filter-function  ',filter-function
+                           bmkp-bmenu-title            ,(format "%s Bookmarks" (capitalize type)))
+                     (let ((bookmark-alist  (funcall bmkp-bmenu-filter-function)))
+                       (setq bmkp-latest-bookmark-alist  bookmark-alist)
+                       (bookmark-bmenu-list 'filteredp))
+                     (when (interactive-p)
+                       (bmkp-msg-about-sort-order (bmkp-current-sort-order)
+                                                  ,(format "Only %s bookmarks are shown" type))))
+            (error (progn (setq bmkp-bmenu-filter-function  orig-filter-fn
+                                bmkp-bmenu-title            orig-title
+                                bmkp-latest-bookmark-alist  orig-latest-alist)
+                          (error "%s" (error-message-string err))))))))))
+
+;;;###autoload (autoload 'bmkp-define-sort-command "bookmark+")
+(defmacro bmkp-define-sort-command (sort-order comparer doc-string)
+  "Define a command to sort bookmarks in the bookmark list by SORT-ORDER.
+SORT-ORDER is a short string or symbol describing the sorting method.
+Examples: \"by last access time\", \"by bookmark name\".
+
+The new command is named by replacing any spaces in SORT-ORDER with
+hyphens (`-') and then adding the prefix `bmkp-bmenu-sort-'.  Example:
+`bmkp-bmenu-sort-by-bookmark-name', for SORT-ORDER `by bookmark name'.
+
+COMPARER compares two bookmarks, returning non-nil if and only if the
+first bookmark sorts before the second.  It must be acceptable as a
+value of `bmkp-sort-comparer'.  That is, it is either nil, a
+predicate, or a list ((PRED...) FINAL-PRED).  See the doc for
+`bmkp-sort-comparer'.
+
+DOC-STRING is the doc string of the new command."
+  (unless (stringp sort-order) (setq sort-order  (symbol-name sort-order)))
+  (let ((command  (intern (concat "bmkp-bmenu-sort-" (bmkp-replace-regexp-in-string
+                                                      "\\s-+" "-" sort-order)))))
+    `(progn
+      (setq bmkp-sort-orders-alist  (bmkp-assoc-delete-all ,sort-order (copy-sequence
+                                                                        bmkp-sort-orders-alist)))
+      (setq bmkp-sort-orders-alist  (cons (cons ,sort-order ',comparer) bmkp-sort-orders-alist))
+      (defun ,command ()
+        ,(concat doc-string "\nRepeating this command cycles among normal sort, reversed \
+sort, and unsorted.")
+        (interactive)
+        (bmkp-bmenu-barf-if-not-in-menu-list)
+        (cond (;; Not this sort order - make it this sort order.
+               (not (equal bmkp-sort-comparer ',comparer))
+               (setq bmkp-sort-comparer   ',comparer
+                     bmkp-reverse-sort-p  nil))
+              (;; Not this sort order reversed - make it reversed.
+               (not bmkp-reverse-sort-p)
+               (setq bmkp-reverse-sort-p  t))
+              (t;; This sort order reversed.  Change to unsorted.
+               (setq bmkp-sort-comparer   nil)))
+        (message "Sorting...")
+        (bookmark-bmenu-ensure-position)
+        (let ((current-bmk  (bookmark-bmenu-bookmark)))
+          (bookmark-bmenu-surreptitiously-rebuild-list)
+          (when current-bmk             ; Should be non-nil, but play safe.
+            (bmkp-bmenu-goto-bookmark-named current-bmk))) ; Put cursor back on right line.
+        (when (interactive-p)
+          (bmkp-msg-about-sort-order
+           ,sort-order
+           nil
+           (cond ((and (not bmkp-reverse-sort-p)
+                       (equal bmkp-sort-comparer ',comparer)) "(Repeat: reverse)")
+                 ((equal bmkp-sort-comparer ',comparer)       "(Repeat: unsorted)")
+                 (t                                           "(Repeat: sort)"))))))))
+
+;;;###autoload (autoload 'bmkp-define-file-sort-predicate "bookmark+")
+(defmacro bmkp-define-file-sort-predicate (att-nb)
+  "Define a predicate for sorting bookmarks by file attribute ATT-NB.
+See function `file-attributes' for the meanings of the various file
+attribute numbers.
+
+String attribute values sort alphabetically; numerical values sort
+numerically; nil sorts before t.
+
+For ATT-NB 0 (file type), a file sorts before a symlink, which sorts
+before a directory.
+
+For ATT-NB 2 or 3 (uid, gid), a numerical value sorts before a string
+value.
+
+A bookmark that has file attributes sorts before a bookmark that does
+not.  A file bookmark sorts before a non-file bookmark.  Only local
+files are tested for attributes - remote-file bookmarks are treated
+here like non-file bookmarks."
+  `(defun ,(intern (format "bmkp-file-attribute-%d-cp" att-nb)) (b1 b2)
+    ,(format "Sort file bookmarks by attribute %d.
+Sort bookmarks with file attributes before those without attributes
+Sort file bookmarks before non-file bookmarks.
+Treat remote file bookmarks like non-file bookmarks.
+
+B1 and B2 are full bookmarks (records) or bookmark names.
+If either is a record then it need not belong to `bookmark-alist'."
+             att-nb)
+    (setq b1  (bmkp-get-bookmark b1))
+    (setq b2  (bmkp-get-bookmark b2))
+    (let (a1 a2)
+      (cond (;; Both are file bookmarks.
+             (and (bmkp-file-bookmark-p b1) (bmkp-file-bookmark-p b2))
+             (setq a1  (file-attributes (bookmark-get-filename b1))
+                   a2  (file-attributes (bookmark-get-filename b2)))
+             (cond (;; Both have attributes.
+                    (and a1 a2)
+                    (setq a1  (nth ,att-nb a1)
+                          a2  (nth ,att-nb a2))
+                    ;; Convert times and maybe inode number to floats.
+                    ;; The inode conversion is kludgy, but is probably OK in practice.
+                    (when (consp a1) (setq a1  (bmkp-float-time a1)))
+                    (when (consp a2) (setq a2  (bmkp-float-time a2)))
+                    (cond (;; (1) links, (2) maybe uid, (3) maybe gid, (4, 5, 6) times
+                           ;; (7) size, (10) inode, (11) device.
+                           (numberp a1)
+                           (cond ((< a1 a2)  '(t))
+                                 ((> a1 a2)  '(nil))
+                                 (t          nil)))
+                          ((= 0 ,att-nb) ; (0) file (nil) < symlink (string) < dir (t)
+                           (cond ((and a2 (not a1))               '(t)) ; file vs (symlink or dir)
+                                 ((and a1 (not a2))               '(nil))
+                                 ((and (eq t a2) (not (eq t a1))) '(t)) ; symlink vs dir
+                                 ((and (eq t a1) (not (eq t a2))) '(t))
+                                 ((and (stringp a1) (stringp a2))
+                                  (if (string< a1 a2) '(t) '(nil)))
+                                 (t                               nil)))
+                          ((stringp a1) ; (2, 3) string uid/gid, (8) modes
+                           (cond ((string< a1 a2)  '(t))
+                                 ((string< a2 a1)  '(nil))
+                                 (t                nil)))
+                          ((eq ,att-nb 9) ; (9) gid would change if re-created. nil < t
+                           (cond ((and a2 (not a1))  '(t))
+                                 ((and a1 (not a2))  '(nil))
+                                 (t                  nil)))))
+                   (;; First has attributes, but not second.
+                    a1
+                    '(t))
+                   (;; Second has attributes, but not first.
+                    a2
+                    '(nil))
+                   (;; Neither has attributes.
+                    t
+                    nil)))
+            (;; First is a file, second is not.
+             (bmkp-local-file-bookmark-p b1)
+             '(t))
+            (;; Second is a file, first is not.
+             (bmkp-local-file-bookmark-p b2)
+             '(nil))
+            (t;; Neither is a file.
+             nil)))))
+
+;;; This is also defined in `bookmark+-1.el'.  It is used here to produce the code for
+;;; `bmkp-define-history-variables' and `bmkp-define-sort-command'.
+;;;
+(defun bmkp-types-alist ()
+  "Alist of bookmark types used by `bmkp-jump-to-type'.
+Keys are bookmark type names.  Values are corresponding history variables.
+The alist is used in commands such as `bmkp-jump-to-type'."
+  (let ((entries  ()))
+    (mapatoms
+     (lambda (sym)
+       (let ((name  (symbol-name sym)))
+         (when (string-match "\\`bmkp-\\(.+\\)-alist-only\\'" name)
+           (push (cons (match-string 1 name)
+                       (intern (format "bmkp-%s-history" (match-string 1 name))))
+                 entries)))))
+    entries))
+
+;; Macro that defines Bookmark+ history variables.
+;; Use this after you define any new filter function, `bmkp-*-alist-only',
+;; for a new kind of bookmark.
+;;
+;;;###autoload (autoload 'bmkp-define-history-variables "bookmark+")
+(defmacro bmkp-define-history-variables ()
+  "Create and eval defvars for Bookmark+ history variables.
+The variables are the cdrs of `bmkp-types-alist'.  They are used in
+commands such as `bmkp-jump-to-type'."
+  (dolist (entry  (bmkp-types-alist))
+    `(defvar,(cdr entry) ()
+       ,(format "History for %s bookmarks." (car entry)))))
+
+;; This is compatible with Emacs 20 and later.
+;;;###autoload (autoload 'bmkp-menu-bar-make-toggle "bookmark+")
+(defmacro bmkp-menu-bar-make-toggle (command variable item-name message help
+                                     &optional setting-sexp &rest keywords)
+  "Define a menu-bar toggle command.
+COMMAND (a symbol) is the toggle command to define.
+VARIABLE (a symbol) is the variable to set.
+ITEM-NAME (a string) is the menu-item name.
+MESSAGE is a format string for the toggle message, with %s for the new
+ status.
+HELP (a string) is the `:help' tooltip text and the doc string first
+ line (minus final period) for the command.
+SETTING-SEXP is a Lisp sexp that sets VARIABLE, or it is nil meaning
+ set it according to its `defcustom' or using `set-default'.
+KEYWORDS is a plist for `menu-item' for keywords other than `:help'."
+  `(progn
+    (defun ,command (&optional interactively)
+      ,(concat help ".
+In an interactive call, record this option as a candidate for saving
+by \"Save Options\" in Custom buffers.")
+      (interactive "p")
+      (if ,(if setting-sexp
+               `,setting-sexp
+               `(progn
+                (custom-load-symbol ',variable)
+                (let ((set (or (get ',variable 'custom-set) 'set-default))
+                      (get (or (get ',variable 'custom-get) 'default-value)))
+                  (funcall set ',variable (not (funcall get ',variable))))))
+          (message ,message "enabled globally")
+        (message ,message "disabled globally"))
+      ;; `customize-mark-as-set' must only be called when a variable is set interactively,
+      ;; because the purpose is to mark the variable as a candidate for `Save Options', and we
+      ;; do not want to save options that the user has already set explicitly in the init file.
+      (when (and interactively  (fboundp 'customize-mark-as-set))
+        (customize-mark-as-set ',variable)))
+    '(menu-item ,item-name ,command
+      :help ,help
+      :button (:toggle . (and (default-boundp ',variable) (default-value ',variable)))
+      ,@keywords)))
+
+;;; Not used currently.  Provided so you can use it in your own code, if appropriate.
+;;;###autoload (autoload 'bmkp-with-bookmark-dir "bookmark+")
+(defmacro bmkp-with-bookmark-dir (bookmark &rest body)
+  "Evaluate BODY forms with BOOKMARK location as `default-directory'.
+If BOOKMARK has no location then use nil as `default-directory'."
+  `(let* ((loc                (bookmark-location ,bookmark))
+          (default-directory  (and (stringp loc)  (not (member loc (list bmkp-non-file-filename
+                                                                    "-- Unknown location --")))
+                               (if (file-directory-p loc) loc (file-name-directory loc)))))
+    ,@body))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'bookmark+-mac)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; bookmark+-mac.el ends here
diff --git a/lisp/bookmark+.el b/lisp/bookmark+.el
new file mode 100644 (file)
index 0000000..690d4ed
--- /dev/null
@@ -0,0 +1,243 @@
+;;; bookmark+.el --- Bookmark+: extensions to standard library `bookmark.el'.
+;;
+;; Filename: bookmark+.el
+;; Description: Bookmark+: extensions to standard library `bookmark.el'.
+;; Author: Drew Adams, Thierry Volpiatto
+;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com")
+;; Copyright (C) 2000-2022, Drew Adams, all rights reserved.
+;; Copyright (C) 2009, Thierry Volpiatto, all rights reserved.
+;; Created: Fri Sep 15 07:58:41 2000
+;; Version: 2021.09.19
+;; Last-Updated: Fri Jan 14 12:52:46 2022 (-0800)
+;;           By: dradams
+;;     Update #: 15072
+;; URL: https://www.emacswiki.org/emacs/download/bookmark%2b.el
+;; Doc URL: https://www.emacswiki.org/emacs/BookmarkPlus
+;; Keywords: bookmarks, bookmark+, projects, placeholders, annotations, search, info, url, eww, w3m, gnus
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x, 24.x, 25.x, 26.x
+;;
+;; Features that might be required by this library:
+;;
+;;   `apropos', `apropos+', `avoid', `backquote', `bookmark',
+;;   `bookmark+', `bookmark+-1', `bookmark+-bmu', `bookmark+-key',
+;;   `bookmark+-lit', `button', `bytecomp', `cconv', `cl', `cl-lib',
+;;   `cmds-menu', `col-highlight', `crosshairs', `fit-frame',
+;;   `font-lock', `font-lock+', `frame-fns', `gv', `help+',
+;;   `help-fns', `help-fns+', `help-macro', `help-macro+',
+;;   `help-mode', `hl-line', `hl-line+', `info', `info+', `kmacro',
+;;   `macroexp', `menu-bar', `menu-bar+', `misc-cmds', `misc-fns',
+;;   `naked', `pp', `pp+', `radix-tree', `rect', `replace',
+;;   `second-sel', `strings', `syntax', `text-mode', `thingatpt',
+;;   `thingatpt+', `vline', `w32browser-dlgopen', `wid-edit',
+;;   `wid-edit+'.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;    Bookmark+: extensions to standard library `bookmark.el'.
+;;
+;;    The Bookmark+ libraries are these:
+;;
+;;    `bookmark+.el'     - main (driver) library (this file)
+;;    `bookmark+-mac.el' - Lisp macros
+;;    `bookmark+-lit.el' - (optional) code for highlighting bookmarks
+;;    `bookmark+-bmu.el' - code for the `*Bookmark List*' (bmenu)
+;;    `bookmark+-1.el'   - other required code (non-bmenu)
+;;    `bookmark+-key.el' - key and menu bindings
+;;
+;;    `bookmark+-doc.el' - documentation (comment-only file)
+;;    `bookmark+-chg.el' - change log (comment-only file)
+;;
+;;    The documentation (in `bookmark+-doc.el') includes how to
+;;    byte-compile and install Bookmark+.  The documentation is also
+;;    available in these ways:
+;;
+;;    1. From the bookmark list (`C-x r l'):
+;;       Use `?' to show the current bookmark-list status and general
+;;       help, then click link `Doc in Commentary' or link `Doc on the
+;;       Web'.
+;;
+;;    2. From the Emacs-Wiki Web site:
+;;       https://www.emacswiki.org/emacs/BookmarkPlus.
+;;
+;;    3. From the Bookmark+ group customization buffer:
+;;       `M-x customize-group bookmark-plus', then click link
+;;       `Commentary'.
+;;
+;;    (The commentary links in #1 and #3 work only if you have library
+;;    `bookmark+-doc.el' in your `load-path'.)
+;;
+;;    To report Bookmark+ bugs: `M-x customize-group bookmark-plus'
+;;    and then follow (e.g. click) the link `Send Bug Report', which
+;;    helps you prepare an email to me.
+;;
+;;
+;;    ****** NOTE ******
+;;
+;;      Whenever you update Bookmark+ (i.e., download new versions of
+;;      Bookmark+ source files), I recommend that you do the
+;;      following:
+;;
+;;      1. Delete all existing byte-compiled Bookmark+ files
+;;         (bookmark+*.elc).
+;;      2. Load Bookmark+ (`load-library' or `require').
+;;      3. Byte-compile the source files.
+;;
+;;      In particular, always load `bookmark+-mac.el' (not
+;;      `bookmark+-mac.elc') before you byte-compile new versions of
+;;      the files, in case there have been any changes to Lisp macros
+;;      (in `bookmark+-mac.el').
+;;
+;;    ******************
+;;
+;;
+;;    ****** NOTE ******
+;;
+;;      On 2010-06-18, I changed the prefix used by package Bookmark+
+;;      from `bookmarkp-' to `bmkp-'.  THIS IS AN INCOMPATIBLE CHANGE.
+;;      I apologize for the inconvenience, but the new prefix is
+;;      preferable for a number of reasons, including easier
+;;      distinction from standard `bookmark.el' names.
+;;
+;;      This change means that YOU MUST MANUALLY REPLACE ALL
+;;      OCCURRENCES of `bookmarkp-' by `bmkp-' in the following
+;;      places, if you used Bookmark+ prior to this change:
+;;
+;;      1. In your init file (`~/.emacs') or your `custom-file', if
+;;         you have one.  This is needed if you customized any
+;;         Bookmark+ features.
+;;
+;;      2. In your default bookmark file, `bookmark-default-file'
+;;         (`~/.emacs.bmk'), and in any other bookmark files you might
+;;         have.
+;;
+;;      3. In your `*Bookmark List*' state file,
+;;         `bmkp-bmenu-state-file' (`~/.emacs-bmk-bmenu-state.el').
+;;
+;;      4. In your `*Bookmark List*' commands file,
+;;         `bmkp-bmenu-commands-file' (`~/.emacs-bmk-bmenu-commands.el'),
+;;         if you have one.
+;;
+;;      You can do this editing in a virgin Emacs session (`emacs
+;;      -Q'), that is, without loading Bookmark+.
+;;
+;;      Alternatively, you can do this editing in an Emacs session
+;;      where Bookmark+ has been loaded, but in that case you must
+;;      TURN OFF AUTOMATIC SAVING of both your default bookmark file
+;;      and your `*Bookmark List*' state file.  Otherwise, when you
+;;      quit Emacs your manually edits will be overwritten.
+;;
+;;      To turn off this automatic saving, you can use `M-~' and `M-l'
+;;      in buffer `*Bookmark List*' (commands
+;;      `bmkp-toggle-saving-bookmark-file' and
+;;      `bmkp-toggle-saving-menu-list-state' - they are also in the
+;;      `Bookmark+' menu).
+;;
+;;
+;;      Again, sorry for this inconvenience.
+;;
+;;    ******************
+;;
+;;
+;;  Commands defined here:
+;;
+;;    `bmkp-version'.
+;;
+;;  Internal variables defined here:
+;;
+;;    `bmkp-version-number'.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;
+
+(require 'bookmark)                     ; Vanilla Emacs.
+
+;;;###autoload (autoload 'bmkp-version-number "bookmark+")
+(defconst bmkp-version-number "2018.10.17")
+
+;;;###autoload (autoload 'bmkp-version "bookmark+")
+(defun bmkp-version ()
+  "Show version number of library `bookmark+.el'."
+  (interactive)
+  (message "Bookmark+, version %s" bmkp-version-number))
+
+;; This was made automatically buffer-local for vanilla Emacs 28.  Do it here, for all Bookmark+ files.
+(defvar bookmark-annotation-name nil
+  "Name of bookmark under edit in `bookmark-edit-annotation-mode'.")
+(make-variable-buffer-local 'bookmark-annotation-name)
+
+;;;###autoload (autoload 'bookmark-bmenu-buffer "bookmark+")
+;; This was added for vanilla Emacs 28.  Add it here for older releases.
+(defconst bookmark-bmenu-buffer "*Bookmark List*"
+  "Name of buffer used by vanilla Emacs for the bookmark-list display.")
+
+;;;###autoload (autoload 'bookmark-plus "bookmark+")
+(defgroup bookmark-plus nil
+  "Bookmark enhancements."
+  :prefix "bmkp-" :group 'bookmark
+  :link `(url-link :tag "Send Bug Report"
+          ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\
+Bookmark+ bug: \
+&body=Describe bug here, starting with `emacs -Q'.  \
+Don't forget to mention your Emacs and library versions."))
+  :link '(url-link :tag "Download" "https://www.emacswiki.org/emacs/download/bookmark%2b.el")
+  :link '(url-link :tag "Description" "https://www.emacswiki.org/emacs/BookmarkPlus")
+  :link '(emacs-commentary-link :tag "Commentary" "bookmark+"))
+
+;; NOTE:
+;; $$$$$$ Currently all vanilla Emacs functions that use constant `bookmark-bmenu-buffer' are
+;; already redefined for Bookmark+.  But if vanilla Emacs adds more such functions, and if those
+;; functions could be invoked somehow when using Bookmark+, and if `bmkp-bmenu-buffer' has a
+;; different value from `bookmark-bmenu-buffer', then some adjustment of Bookmark+ code will be
+;; needed, to make sure the `bmkp-bmenu-buffer' value gets used instead.
+;;
+;;;###autoload (autoload 'bmkp-bmenu-buffer "bookmark+")
+(defcustom bmkp-bmenu-buffer bookmark-bmenu-buffer
+  "Name of buffer used by Bookmark+ for the bookmark-list display.
+The default value is that of vanilla Emacs constant `bookmark-bmenu-buffer'."
+  :type 'string :group 'bookmark-plus)
+
+
+
+;; Load Bookmark+ libraries.
+;;
+(eval-when-compile
+ (or (condition-case nil
+         (load-library "bookmark+-mac") ; Lisp macros.
+       (error nil))                     ; Use load-library to ensure latest .elc.
+     (require 'bookmark+-mac)))         ; Require, so can load separately if not on `load-path'.
+
+(require 'bookmark+-lit nil t)          ; Optional (soft require) - no error if not found.  If you do
+                                        ; not want to use `bookmark+-lit.el' then simply do not put
+                                        ; that file in your `load-path'.
+(require 'bookmark+-bmu)                ; `*Bookmark List*' (aka "menu list") stuff.
+(require 'bookmark+-1)                  ; Rest of Bookmark+, except keys & menus.
+(require 'bookmark+-key)                ; Keys & menus.
+
+;;;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'bookmark+)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; bookmark+.el ends here