;;; bookmark.el --- set bookmarks, maybe annotate them, jump to them later
-;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 2001, 2002, 2003,
-;; 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+;; Copyright (C) 1993-1997, 2001-2012 Free Software Foundation, Inc.
;; Author: Karl Fogel <kfogel@red-bean.com>
;; Maintainer: Karl Fogel <kfogel@red-bean.com>
;; can navigate your way to that location by providing the string.
;; See the "User Variables" section for customizations.
-;; Thanks to David Bremner <bremner@cs.sfu.ca> for thinking of and
-;; then implementing the bookmark-current-bookmark idea. He even
-;; sent *patches*, bless his soul...
-
-;; Thanks to Gregory M. Saunders <saunders@cis.ohio-state.edu> for
-;; fixing and improving bookmark-time-to-save-p.
-
-;; Thanks go to Andrew V. Klein <avk@cig.mot.com> for the code that
-;; sorts the alist before presenting it to the user (in bookmark-bmenu-list
-;; and the menu-bar).
-
-;; And much thanks to David Hughes <djh@harston.cv.com> for many small
-;; suggestions and the code to implement them (like
-;; bookmark-bmenu-check-position, and some of the Lucid compatibility
-;; stuff).
-
-;; Kudos (whatever they are) go to Jim Blandy <jimb@red-bean.com>
-;; for his eminently sensible suggestion to separate bookmark-jump
-;; into bookmark-jump and bookmark-jump-noselect, which made many
-;; other things cleaner as well.
-
-;; Thanks to Roland McGrath for encouragement and help with defining
-;; autoloads on the menu-bar.
-
-;; Jonathan Stigelman <stig@hackvan.com> gave patches for default
-;; values in bookmark-jump and bookmark-set. Everybody please keep
-;; all the keystrokes they save thereby and send them to him at the
-;; end of each year :-) (No, seriously, thanks Jonathan!)
-
-;; Buckets of gratitude to John Grabowski <johng@media.mit.edu> for
-;; thinking up the annotations feature and implementing it so well.
-
-;; Based on info-bookmark.el, by Karl Fogel and Ken Olstad
-;; <olstad@msc.edu>.
-
-;; Thanks to Mikio Nakajima <PBC01764@niftyserve.or.jp> for many bugs
-;; reported and fixed.
-
-;; Thank you, Michael Kifer, for contributing the XEmacs support.
-
-;; Enough with the credits already, get on to the good stuff:
-
-;; FAVORITE CHINESE RESTAURANT:
-;; Boy, that's a tough one. Probably Hong Min, or maybe Emperor's
-;; Choice (both in Chicago's Chinatown). Well, both. How about you?
\f
;;; Code:
(require 'pp)
-(eval-when-compile (require 'cl))
+(eval-when-compile (require 'cl-lib))
;;; Misc comments:
;;
--> t means save bookmarks when Emacs is killed.
--> Otherwise, it should be a number that is the frequency with which
the bookmark list is saved (i.e.: the number of times which
- Emacs' bookmark list may be modified before it is automatically
+ Emacs's bookmark list may be modified before it is automatically
saved.). If it is a number, Emacs will also automatically save
bookmarks when it is killed.
"The `.emacs.bmk' file used to be called this name.")
-;; defvarred to avoid a compilation warning:
+;; defvared to avoid a compilation warning:
(defvar bookmark-file nil
"Old name for `bookmark-default-file'.")
(if bookmark-file
;; In case user set `bookmark-file' in her .emacs:
bookmark-file
- (convert-standard-filename "~/.emacs.bmk"))
+ (locate-user-emacs-file "bookmarks" ".emacs.bmk"))
"File in which to save bookmarks by default."
:type 'file
:group 'bookmark)
:group 'bookmark)
+(defconst bookmark-bmenu-header-height 2
+ "Number of lines used for the *Bookmark List* header.")
+
+(defconst bookmark-bmenu-marks-width 2
+ "Number of columns (chars) used for the *Bookmark List* marks column,
+including the annotations column.")
+
(defcustom bookmark-bmenu-file-column 30
"Column at which to display filenames in a buffer listing bookmarks.
You can toggle whether files are shown with \\<bookmark-bmenu-mode-map>\\[bookmark-bmenu-toggle-filenames]."
(defvar bookmark-current-buffer nil
"The buffer in which a bookmark is currently being set or renamed.
Functions that insert strings into the minibuffer use this to know
-the source buffer for that information; see `bookmark-yank-word' and
-`bookmark-insert-current-bookmark' for example.")
+the source buffer for that information; see `bookmark-yank-word'
+for example.")
(defvar bookmark-yank-point 0
(defvar bookmark-quit-flag nil
"Non nil make `bookmark-bmenu-search' quit immediately.")
\f
-;; Helper functions.
-
-;; Only functions on this page and the next one (file formats) need to
-;; know anything about the format of bookmark-alist entries.
+;; Helper functions and macros.
+
+(defmacro with-buffer-modified-unmodified (&rest body)
+ "Run BODY while preserving the buffer's `buffer-modified-p' state."
+ (let ((was-modified (make-symbol "was-modified")))
+ `(let ((,was-modified (buffer-modified-p)))
+ (unwind-protect
+ (progn ,@body)
+ (set-buffer-modified-p ,was-modified)))))
+
+;; Only functions below, in this page and the next one (file formats),
+;; need to know anything about the format of bookmark-alist entries.
;; Everyone else should go through them.
-
-(defun bookmark-name-from-full-record (full-record)
- "Return name of FULL-RECORD (an alist element instead of a string)."
- (car full-record))
+(defun bookmark-name-from-full-record (bookmark-record)
+ "Return the name of BOOKMARK-RECORD. BOOKMARK-RECORD is, e.g.,
+one element from `bookmark-alist'."
+ (car bookmark-record))
(defun bookmark-all-names ()
(mapcar 'bookmark-name-from-full-record bookmark-alist))
-(defun bookmark-get-bookmark (bookmark &optional noerror)
- "Return the bookmark record corresponding to BOOKMARK.
-If BOOKMARK is a string, look for the corresponding bookmark record in
-`bookmark-alist'; return it if found, otherwise error. Else if
-BOOKMARK is already a bookmark record, just return it."
+(defun bookmark-get-bookmark (bookmark-name-or-record &optional noerror)
+ "Return the bookmark record corresponding to BOOKMARK-NAME-OR-RECORD.
+If BOOKMARK-NAME-OR-RECORD is a string, look for the corresponding
+bookmark record in `bookmark-alist'; return it if found, otherwise
+error. Else if BOOKMARK-NAME-OR-RECORD is already a bookmark record,
+just return it."
(cond
- ((consp bookmark) bookmark)
- ((stringp bookmark)
- (or (assoc-string bookmark bookmark-alist bookmark-completion-ignore-case)
- (unless noerror (error "Invalid bookmark %s" bookmark))))))
-
-
-(defun bookmark-get-bookmark-record (bookmark)
- "Return the record portion of the entry for BOOKMARK in
-`bookmark-alist' (that is, all information but the name).
-BOOKMARK may be a bookmark name (a string) or a bookmark record."
- (let ((alist (cdr (bookmark-get-bookmark bookmark))))
+ ((consp bookmark-name-or-record) bookmark-name-or-record)
+ ((stringp bookmark-name-or-record)
+ (or (assoc-string bookmark-name-or-record bookmark-alist
+ bookmark-completion-ignore-case)
+ (unless noerror (error "Invalid bookmark %s"
+ bookmark-name-or-record))))))
+
+
+(defun bookmark-get-bookmark-record (bookmark-name-or-record)
+ "Return the record portion of the entry for BOOKMARK-NAME-OR-RECORD in
+`bookmark-alist' (that is, all information but the name)."
+ (let ((alist (cdr (bookmark-get-bookmark bookmark-name-or-record))))
;; The bookmark objects can either look like (NAME ALIST) or
;; (NAME . ALIST), so we have to distinguish the two here.
(if (and (null (cdr alist)) (consp (caar alist)))
(car alist) alist)))
-(defun bookmark-set-name (bookmark newname)
- "Set BOOKMARK's name to NEWNAME.
-BOOKMARK may be a bookmark name (a string) or a bookmark record."
- (setcar
- (if (stringp bookmark) (bookmark-get-bookmark bookmark) bookmark)
- newname))
+(defun bookmark-set-name (bookmark-name-or-record newname)
+ "Set BOOKMARK-NAME-OR-RECORD's name to NEWNAME."
+ (setcar (bookmark-get-bookmark bookmark-name-or-record) newname))
-(defun bookmark-prop-get (bookmark prop)
- "Return the property PROP of BOOKMARK, or nil if none.
-BOOKMARK may be a bookmark name (a string) or a bookmark record."
- (cdr (assq prop (bookmark-get-bookmark-record bookmark))))
+(defun bookmark-prop-get (bookmark-name-or-record prop)
+ "Return the property PROP of BOOKMARK-NAME-OR-RECORD, or nil if none."
+ (cdr (assq prop (bookmark-get-bookmark-record bookmark-name-or-record))))
-(defun bookmark-prop-set (bookmark prop val)
- "Set the property PROP of BOOKMARK to VAL.
-BOOKMARK may be a bookmark name (a string) or a bookmark record."
- (let ((cell (assq prop (bookmark-get-bookmark-record bookmark))))
+(defun bookmark-prop-set (bookmark-name-or-record prop val)
+ "Set the property PROP of BOOKMARK-NAME-OR-RECORD to VAL."
+ (let ((cell (assq
+ prop (bookmark-get-bookmark-record bookmark-name-or-record))))
(if cell
(setcdr cell val)
- (nconc (bookmark-get-bookmark-record bookmark)
+ (nconc (bookmark-get-bookmark-record bookmark-name-or-record)
(list (cons prop val))))))
-(defun bookmark-get-annotation (bookmark)
- "Return the annotation of BOOKMARK, or nil if none.
-BOOKMARK may be a bookmark name (a string) or a bookmark record."
- (bookmark-prop-get bookmark 'annotation))
+(defun bookmark-get-annotation (bookmark-name-or-record)
+ "Return the annotation of BOOKMARK-NAME-OR-RECORD, or nil if none."
+ (bookmark-prop-get bookmark-name-or-record 'annotation))
-(defun bookmark-set-annotation (bookmark ann)
- "Set the annotation of BOOKMARK to ANN.
-BOOKMARK may be a bookmark name (a string) or a bookmark record."
- (bookmark-prop-set bookmark 'annotation ann))
+(defun bookmark-set-annotation (bookmark-name-or-record ann)
+ "Set the annotation of BOOKMARK-NAME-OR-RECORD to ANN."
+ (bookmark-prop-set bookmark-name-or-record 'annotation ann))
-(defun bookmark-get-filename (bookmark)
- "Return the full filename of BOOKMARK, or nil if none.
-BOOKMARK may be a bookmark name (a string) or a bookmark record."
- (bookmark-prop-get bookmark 'filename))
+(defun bookmark-get-filename (bookmark-name-or-record)
+ "Return the full filename of BOOKMARK-NAME-OR-RECORD, or nil if none."
+ (bookmark-prop-get bookmark-name-or-record 'filename))
-(defun bookmark-set-filename (bookmark filename)
- "Set the full filename of BOOKMARK to FILENAME.
-BOOKMARK may be a bookmark name (a string) or a bookmark record."
- (bookmark-prop-set bookmark 'filename filename))
+(defun bookmark-set-filename (bookmark-name-or-record filename)
+ "Set the full filename of BOOKMARK-NAME-OR-RECORD to FILENAME."
+ (bookmark-prop-set bookmark-name-or-record 'filename filename))
-(defun bookmark-get-position (bookmark)
- "Return the position (i.e.: point) of BOOKMARK, or nil if none.
-BOOKMARK may be a bookmark name (a string) or a bookmark record."
- (bookmark-prop-get bookmark 'position))
+(defun bookmark-get-position (bookmark-name-or-record)
+ "Return the position (i.e.: point) of BOOKMARK-NAME-OR-RECORD, or nil if none."
+ (bookmark-prop-get bookmark-name-or-record 'position))
-(defun bookmark-set-position (bookmark position)
- "Set the position (i.e.: point) of BOOKMARK to POSITION.
-BOOKMARK may be a bookmark name (a string) or a bookmark record."
- (bookmark-prop-set bookmark 'position position))
+(defun bookmark-set-position (bookmark-name-or-record position)
+ "Set the position (i.e.: point) of BOOKMARK-NAME-OR-RECORD to POSITION."
+ (bookmark-prop-set bookmark-name-or-record 'position position))
-(defun bookmark-get-front-context-string (bookmark)
- "Return the front-context-string of BOOKMARK, or nil if none.
-BOOKMARK may be a bookmark name (a string) or a bookmark record."
- (bookmark-prop-get bookmark 'front-context-string))
+(defun bookmark-get-front-context-string (bookmark-name-or-record)
+ "Return the front-context-string of BOOKMARK-NAME-OR-RECORD, or nil if none."
+ (bookmark-prop-get bookmark-name-or-record 'front-context-string))
-(defun bookmark-set-front-context-string (bookmark string)
- "Set the front-context-string of BOOKMARK to STRING.
-BOOKMARK may be a bookmark name (a string) or a bookmark record."
- (bookmark-prop-set bookmark 'front-context-string string))
+(defun bookmark-set-front-context-string (bookmark-name-or-record string)
+ "Set the front-context-string of BOOKMARK-NAME-OR-RECORD to STRING."
+ (bookmark-prop-set bookmark-name-or-record 'front-context-string string))
-(defun bookmark-get-rear-context-string (bookmark)
- "Return the rear-context-string of BOOKMARK, or nil if none.
-BOOKMARK may be a bookmark name (a string) or a bookmark record."
- (bookmark-prop-get bookmark 'rear-context-string))
+(defun bookmark-get-rear-context-string (bookmark-name-or-record)
+ "Return the rear-context-string of BOOKMARK-NAME-OR-RECORD, or nil if none."
+ (bookmark-prop-get bookmark-name-or-record 'rear-context-string))
-(defun bookmark-set-rear-context-string (bookmark string)
- "Set the rear-context-string of BOOKMARK to STRING.
-BOOKMARK may be a bookmark name (a string) or a bookmark record."
- (bookmark-prop-set bookmark 'rear-context-string string))
+(defun bookmark-set-rear-context-string (bookmark-name-or-record string)
+ "Set the rear-context-string of BOOKMARK-NAME-OR-RECORD to STRING."
+ (bookmark-prop-set bookmark-name-or-record 'rear-context-string string))
-(defun bookmark-get-handler (bookmark)
- "Return the handler function for BOOKMARK, or nil if none.
-BOOKMARK may be a bookmark name (a string) or a bookmark record."
- (bookmark-prop-get bookmark 'handler))
+(defun bookmark-get-handler (bookmark-name-or-record)
+ "Return the handler function for BOOKMARK-NAME-OR-RECORD, or nil if none."
+ (bookmark-prop-get bookmark-name-or-record 'handler))
(defvar bookmark-history nil
"The history list for bookmark functions.")
(defun bookmark-make-record ()
"Return a new bookmark record (NAME . ALIST) for the current location."
(let ((record (funcall bookmark-make-record-function)))
+ ;; Set up defaults.
+ (bookmark-prop-set
+ record 'defaults
+ (delq nil (delete-dups (append (bookmark-prop-get record 'defaults)
+ (list bookmark-current-bookmark
+ (bookmark-buffer-name))))))
;; Set up default name.
(if (stringp (car record))
;; The function already provided a default name.
(setq bookmark-current-bookmark stripped-name)
(bookmark-bmenu-surreptitiously-rebuild-list)))
-(defun bookmark-make-record-default (&optional point-only)
+(defun bookmark-make-record-default (&optional no-file no-context posn)
"Return the record describing the location of a new bookmark.
-Must be at the correct position in the buffer in which the bookmark is
-being set.
-If POINT-ONLY is non-nil, then only return the subset of the
-record that pertains to the location within the buffer."
- `(,@(unless point-only `((filename . ,(bookmark-buffer-file-name))))
- (front-context-string
- . ,(if (>= (- (point-max) (point)) bookmark-search-size)
- (buffer-substring-no-properties
- (point)
- (+ (point) bookmark-search-size))
- nil))
- (rear-context-string
- . ,(if (>= (- (point) (point-min)) bookmark-search-size)
- (buffer-substring-no-properties
- (point)
- (- (point) bookmark-search-size))
- nil))
- (position . ,(point))))
+Point should be at the buffer in which the bookmark is being set,
+and normally should be at the position where the bookmark is desired,
+but see the optional arguments for other possibilities.
+
+If NO-FILE is non-nil, then only return the subset of the
+record that pertains to the location within the buffer, leaving off
+the part that records the filename.
+
+If NO-CONTEXT is non-nil, do not include the front- and rear-context
+strings in the record -- the position is enough.
+
+If POSN is non-nil, record POSN as the point instead of `(point)'."
+ `(,@(unless no-file `((filename . ,(bookmark-buffer-file-name))))
+ ,@(unless no-context `((front-context-string
+ . ,(if (>= (- (point-max) (point))
+ bookmark-search-size)
+ (buffer-substring-no-properties
+ (point)
+ (+ (point) bookmark-search-size))
+ nil))))
+ ,@(unless no-context `((rear-context-string
+ . ,(if (>= (- (point) (point-min))
+ bookmark-search-size)
+ (buffer-substring-no-properties
+ (point)
+ (- (point) bookmark-search-size))
+ nil))))
+ (position . ,(or posn (point)))))
\f
;;; File format stuff
(let ((map (make-sparse-keymap)))
(set-keymap-parent map minibuffer-local-map)
(define-key map "\C-w" 'bookmark-yank-word)
- ;; This C-u binding might not be very useful any more now that we
- ;; provide access to the default via the standard M-n binding.
- ;; Maybe we should just remove it? --Stef-08
- (define-key map "\C-u" 'bookmark-insert-current-bookmark)
map))
;;;###autoload
it removes only the first instance of a bookmark with that name from
the list of bookmarks.)"
(interactive (list nil current-prefix-arg))
- (let* ((record (bookmark-make-record))
- (default (car record)))
-
- (bookmark-maybe-load-default-file)
-
- (setq bookmark-yank-point (point))
- (setq bookmark-current-buffer (current-buffer))
+ (unwind-protect
+ (let* ((record (bookmark-make-record))
+ ;; `defaults' is a transient element of the
+ ;; extensible format described above in the section
+ ;; `File format stuff'. Bookmark record functions
+ ;; can use it to specify a list of default values
+ ;; accessible via M-n while reading a bookmark name.
+ (defaults (bookmark-prop-get record 'defaults))
+ (default (if (consp defaults) (car defaults) defaults)))
+
+ (if defaults
+ ;; Don't store default values in the record.
+ (setq record (assq-delete-all 'defaults record))
+ ;; When no defaults in the record, use its first element.
+ (setq defaults (car record) default defaults))
+
+ (bookmark-maybe-load-default-file)
+ ;; Don't set `bookmark-yank-point' and `bookmark-current-buffer'
+ ;; if they have been already set in another buffer. (e.g gnus-art).
+ (unless (and bookmark-yank-point
+ bookmark-current-buffer)
+ (setq bookmark-yank-point (point))
+ (setq bookmark-current-buffer (current-buffer)))
+
+ (let ((str
+ (or name
+ (read-from-minibuffer
+ (format "Set bookmark (%s): " default)
+ nil
+ bookmark-minibuffer-read-name-map
+ nil nil defaults))))
+ (and (string-equal str "") (setq str default))
+ (bookmark-store str (cdr record) no-overwrite)
+
+ ;; Ask for an annotation buffer for this bookmark
+ (when bookmark-use-annotations
+ (bookmark-edit-annotation str))))
+ (setq bookmark-yank-point nil)
+ (setq bookmark-current-buffer nil)))
- (let ((str
- (or name
- (read-from-minibuffer
- (format "Set bookmark (%s): " default)
- nil
- bookmark-minibuffer-read-name-map
- nil nil default))))
- (and (string-equal str "") (setq str default))
- (bookmark-store str (cdr record) no-overwrite)
-
- ;; Ask for an annotation buffer for this bookmark
- (when bookmark-use-annotations
- (bookmark-edit-annotation str)))))
(defun bookmark-kill-line (&optional newline-too)
"Kill from point to end of line.
If optional arg NEWLINE-TOO is non-nil, delete the newline too.
Does not affect the kill ring."
- (let ((eol (save-excursion (end-of-line) (point))))
+ (let ((eol (line-end-position)))
(delete-region (point) eol)
(if (and newline-too (looking-at "\n"))
(delete-char 1))))
whose annotation is being edited.")
-(defun bookmark-default-annotation-text (bookmark)
- "Return default annotation text for BOOKMARK (a string, not a record).
+(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 "' here.\n"
+ (concat "# Type the annotation for bookmark '" bookmark-name "' here.\n"
"# All lines which start with a '#' will be deleted.\n"
"# Type C-c C-c when done.\n#\n"
"# Author: " (user-full-name) " <" (user-login-name) "@"
"# Date: " (current-time-string) "\n"))
+(define-obsolete-variable-alias 'bookmark-read-annotation-text-func
+ 'bookmark-edit-annotation-text-func "23.1")
(defvar bookmark-edit-annotation-text-func 'bookmark-default-annotation-text
"Function to return default text to use for a bookmark annotation.
It takes one argument, the name of the bookmark, as a string.")
-(define-obsolete-variable-alias 'bookmark-read-annotation-text-func
- 'bookmark-edit-annotation-text-func "23.1")
(defvar bookmark-edit-annotation-mode-map
(let ((map (make-sparse-keymap)))
"Keymap for editing an annotation of a bookmark.")
-(defun bookmark-edit-annotation-mode (bookmark)
- "Mode for editing the annotation of bookmark BOOKMARK.
+(defun bookmark-edit-annotation-mode (bookmark-name-or-record)
+ "Mode for editing the annotation of bookmark BOOKMARK-NAME-OR-RECORD.
When you have finished composing, type \\[bookmark-send-annotation].
-BOOKMARK is a bookmark name (a string) or a bookmark record.
-
\\{bookmark-edit-annotation-mode-map}"
(interactive)
(kill-all-local-variables)
(make-local-variable 'bookmark-annotation-name)
- (setq bookmark-annotation-name bookmark)
+ (setq bookmark-annotation-name bookmark-name-or-record)
(use-local-map bookmark-edit-annotation-mode-map)
(setq major-mode 'bookmark-edit-annotation-mode
mode-name "Edit Bookmark Annotation")
- (insert (funcall bookmark-edit-annotation-text-func bookmark))
- (let ((annotation (bookmark-get-annotation bookmark)))
+ (insert (funcall bookmark-edit-annotation-text-func bookmark-name-or-record))
+ (let ((annotation (bookmark-get-annotation bookmark-name-or-record)))
(if (and annotation (not (string-equal annotation "")))
(insert annotation)))
(run-mode-hooks 'text-mode-hook))
(forward-line 1)))
;; Take no chances with text properties.
(let ((annotation (buffer-substring-no-properties (point-min) (point-max)))
- (bookmark bookmark-annotation-name))
- (bookmark-set-annotation bookmark annotation)
+ (bookmark-name bookmark-annotation-name))
+ (bookmark-set-annotation bookmark-name annotation)
+ (setq bookmark-alist-modification-count
+ (1+ bookmark-alist-modification-count))
(bookmark-bmenu-surreptitiously-rebuild-list))
(kill-buffer (current-buffer)))
-(defun bookmark-edit-annotation (bookmark)
- "Pop up a buffer for editing bookmark BOOKMARK's annotation.
-BOOKMARK is a bookmark name (a string) or a bookmark record."
+(defun bookmark-edit-annotation (bookmark-name-or-record)
+ "Pop up a buffer for editing bookmark BOOKMARK-NAME-OR-RECORD's annotation."
(pop-to-buffer (generate-new-buffer-name "*Bookmark Annotation Compose*"))
- (bookmark-edit-annotation-mode bookmark))
-
-
-(defun bookmark-insert-current-bookmark ()
- "Insert into the bookmark name currently being set the value of
-`bookmark-current-bookmark' in `bookmark-current-buffer', defaulting
-to the buffer's file name if `bookmark-current-bookmark' is nil."
- (interactive)
- (let ((str
- (with-current-buffer bookmark-current-buffer
- (or bookmark-current-bookmark
- (bookmark-buffer-name)))))
- (insert str)))
+ (bookmark-edit-annotation-mode bookmark-name-or-record))
(defun bookmark-buffer-name ()
(and
;; Possibly the old bookmark file, "~/.emacs-bkmrks", needs
;; to be renamed.
- (file-exists-p (expand-file-name bookmark-old-default-file))
- (not (file-exists-p (expand-file-name bookmark-default-file)))
- (rename-file (expand-file-name bookmark-old-default-file)
- (expand-file-name bookmark-default-file)))
+ (file-exists-p bookmark-old-default-file)
+ (not (file-exists-p bookmark-default-file))
+ (rename-file bookmark-old-default-file
+ bookmark-default-file))
;; return t so the `and' will continue...
t)
- (file-readable-p (expand-file-name bookmark-default-file))
+ (file-readable-p bookmark-default-file)
(bookmark-load bookmark-default-file t t)
(setq bookmarks-already-loaded t)))
"Hook run after `bookmark-jump' jumps to a bookmark.
Useful for example to unhide text in `outline-mode'.")
-(defun bookmark--jump-via (bookmark display-function)
- "Handle BOOKMARK, then call DISPLAY-FUNCTION with current buffer as argument.
-Bookmark may be a bookmark name (a string) or a bookmark record.
+(defun bookmark--jump-via (bookmark-name-or-record display-function)
+ "Handle BOOKMARK-NAME-OR-RECORD, then call DISPLAY-FUNCTION with
+current buffer as argument.
After calling DISPLAY-FUNCTION, set window point to the point specified
-by BOOKMARK, if necessary, run `bookmark-after-jump-hook', and then show
-any annotations for this bookmark."
- (bookmark-handle-bookmark bookmark)
+by BOOKMARK-NAME-OR-RECORD, if necessary, run `bookmark-after-jump-hook',
+and then show any annotations for this bookmark."
+ (bookmark-handle-bookmark bookmark-name-or-record)
(save-current-buffer
(funcall display-function (current-buffer)))
(let ((win (get-buffer-window (current-buffer) 0)))
(if bookmark-automatically-show-annotations
;; if there is an annotation for this bookmark,
;; show it in a buffer.
- (bookmark-show-annotation bookmark)))
+ (bookmark-show-annotation bookmark-name-or-record)))
;;;###autoload
will then jump to the new location, as well as recording it in place
of the old one in the permanent bookmark record.
-BOOKMARK may be a bookmark name (a string) or a bookmark record, but
-the latter is usually only used by programmatic callers.
+BOOKMARK is usually a bookmark name (a string). It can also be a
+bookmark record, but this is usually only done by programmatic callers.
If DISPLAY-FUNC is non-nil, it is a function to invoke to display the
bookmark. It defaults to `switch-to-buffer'. A typical value for
(defun bookmark-jump-noselect (bookmark)
- "Return the location pointed to by the bookmark BOOKMARK.
+ "Return the location pointed to by BOOKMARK (see `bookmark-jump').
The return value has the form (BUFFER . POINT).
-BOOKMARK may be a bookmark name (a string) or a bookmark record.
-
Note: this function is deprecated and is present for Emacs 22
compatibility only."
(save-excursion
(make-obsolete 'bookmark-jump-noselect 'bookmark-handle-bookmark "23.1")
-(defun bookmark-handle-bookmark (bookmark)
- "Call BOOKMARK's handler or `bookmark-default-handler' if it has none.
-BOOKMARK may be a bookmark name (a string) or a bookmark record.
-
-Changes current buffer and point and returns nil, or signals a `file-error'.
+(defun bookmark-handle-bookmark (bookmark-name-or-record)
+ "Call BOOKMARK-NAME-OR-RECORD's handler or `bookmark-default-handler'
+if it has none. This changes current buffer and point and returns nil,
+or signals a `file-error'.
-If BOOKMARK has no file, this is a no-op. If BOOKMARK has a file, but
-that file no longer exists, then offer interactively to relocate BOOKMARK."
+If BOOKMARK-NAME-OR-RECORD has no file, this is a no-op. If
+BOOKMARK-NAME-OR-RECORD has a file, but that file no longer exists,
+then offer interactively to relocate BOOKMARK-NAME-OR-RECORD."
(condition-case err
- (funcall (or (bookmark-get-handler bookmark)
+ (funcall (or (bookmark-get-handler bookmark-name-or-record)
'bookmark-default-handler)
- (bookmark-get-bookmark bookmark))
- (file-error
+ (bookmark-get-bookmark bookmark-name-or-record))
+ (bookmark-error-no-filename ;file-error
;; We were unable to find the marked file, so ask if user wants to
;; relocate the bookmark, else remind them to consider deletion.
- (when (stringp bookmark)
- ;; `bookmark' can be either a bookmark name (from `bookmark-alist')
- ;; or a bookmark object. If it's an object, we assume it's a
- ;; bookmark used internally by some other package.
- (let ((file (bookmark-get-filename bookmark)))
+ (when (stringp bookmark-name-or-record)
+ ;; `bookmark-name-or-record' can be either a bookmark name
+ ;; (from `bookmark-alist') or a bookmark object. If it's an
+ ;; object, we assume it's a bookmark used internally by some
+ ;; other package.
+ (let ((file (bookmark-get-filename bookmark-name-or-record)))
(when file ;Don't know how to relocate if there's no `file'.
;; If file is not a dir, directory-file-name just returns file.
(let ((display-name (directory-file-name file)))
(let ((use-dialog-box nil)
(use-file-dialog nil))
(if (y-or-n-p (concat display-name " nonexistent. Relocate \""
- bookmark "\"? "))
+ bookmark-name-or-record "\"? "))
(progn
- (bookmark-relocate bookmark)
+ (bookmark-relocate bookmark-name-or-record)
;; Try again.
- (funcall (or (bookmark-get-handler bookmark)
+ (funcall (or (bookmark-get-handler bookmark-name-or-record)
'bookmark-default-handler)
- (bookmark-get-bookmark bookmark)))
+ (bookmark-get-bookmark bookmark-name-or-record)))
(message
"Bookmark not relocated; consider removing it (%s)."
- bookmark)
+ bookmark-name-or-record)
(signal (car err) (cdr err))))))))))
;; Added by db.
- (when (stringp bookmark)
- (setq bookmark-current-bookmark bookmark))
+ (when (stringp bookmark-name-or-record)
+ (setq bookmark-current-bookmark bookmark-name-or-record))
nil)
(put 'bookmark-error-no-filename
BMK-RECORD is a bookmark record, not a bookmark name (i.e., not a string).
Changes current buffer and point and returns nil, or signals a `file-error'."
(let ((file (bookmark-get-filename bmk-record))
+ (buf (bookmark-prop-get bmk-record 'buffer))
(forward-str (bookmark-get-front-context-string bmk-record))
(behind-str (bookmark-get-rear-context-string bmk-record))
(place (bookmark-get-position bmk-record)))
- (if (not file)
- (signal 'bookmark-error-no-filename (list 'stringp file))
- (set-buffer (find-file-noselect file))
- (if place (goto-char place))
- ;; Go searching forward first. Then, if forward-str exists and
- ;; was found in the file, we can search backward for behind-str.
- ;; Rationale is that if text was inserted between the two in the
- ;; file, it's better to be put before it so you can read it,
- ;; rather than after and remain perhaps unaware of the changes.
- (if forward-str
- (if (search-forward forward-str (point-max) t)
- (goto-char (match-beginning 0))))
- (if behind-str
- (if (search-backward behind-str (point-min) t)
- (goto-char (match-end 0)))))
+ (set-buffer
+ (cond
+ ((and file (file-readable-p file) (not (buffer-live-p buf)))
+ (find-file-noselect file))
+ ;; No file found. See if buffer BUF have been created.
+ ((and buf (get-buffer buf)))
+ (t ;; If not, raise error.
+ (signal 'bookmark-error-no-filename (list 'stringp file)))))
+ (if place (goto-char place))
+ ;; Go searching forward first. Then, if forward-str exists and
+ ;; was found in the file, we can search backward for behind-str.
+ ;; Rationale is that if text was inserted between the two in the
+ ;; file, it's better to be put before it so you can read it,
+ ;; rather than after and remain perhaps unaware of the changes.
+ (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)))
nil))
;;;###autoload
-(defun bookmark-relocate (bookmark)
- "Relocate BOOKMARK to another file (reading file name with minibuffer).
-BOOKMARK is a bookmark name (a string), not a bookmark record.
+(defun bookmark-relocate (bookmark-name)
+ "Relocate BOOKMARK-NAME to another file, reading file name with minibuffer.
This makes an already existing bookmark point to that file, instead of
the one it used to point at. Useful when a file has been renamed
after a bookmark was set in it."
(interactive (list (bookmark-completing-read "Bookmark to relocate")))
- (bookmark-maybe-historicize-string bookmark)
+ (bookmark-maybe-historicize-string bookmark-name)
(bookmark-maybe-load-default-file)
- (let* ((bmrk-filename (bookmark-get-filename bookmark))
- (newloc (expand-file-name
- (read-file-name
- (format "Relocate %s to: " bookmark)
- (file-name-directory bmrk-filename)))))
- (bookmark-set-filename bookmark newloc)
+ (let* ((bmrk-filename (bookmark-get-filename bookmark-name))
+ (newloc (abbreviate-file-name
+ (expand-file-name
+ (read-file-name
+ (format "Relocate %s to: " bookmark-name)
+ (file-name-directory bmrk-filename))))))
+ (bookmark-set-filename bookmark-name newloc)
(setq bookmark-alist-modification-count
(1+ bookmark-alist-modification-count))
(if (bookmark-time-to-save-p)
;;;###autoload
-(defun bookmark-insert-location (bookmark &optional no-history)
- "Insert the name of the file associated with BOOKMARK.
-BOOKMARK is a bookmark name (a string), not a bookmark record.
+(defun bookmark-insert-location (bookmark-name &optional no-history)
+ "Insert the name of the file associated with BOOKMARK-NAME.
Optional second arg NO-HISTORY means don't record this in the
minibuffer history list `bookmark-history'."
(interactive (list (bookmark-completing-read "Insert bookmark location")))
- (or no-history (bookmark-maybe-historicize-string bookmark))
+ (or no-history (bookmark-maybe-historicize-string bookmark-name))
(let ((start (point)))
(prog1
- (insert (bookmark-location bookmark)) ; *Return this line*
+ (insert (bookmark-location bookmark-name))
(if (display-mouse-p)
(add-text-properties
start
;;;###autoload
(defalias 'bookmark-locate 'bookmark-insert-location)
-(defun bookmark-location (bookmark)
- "Return the name of the file associated with BOOKMARK, or nil if none.
-BOOKMARK may be a bookmark name (a string) or a bookmark record."
+(defun bookmark-location (bookmark-name-or-record)
+ "Return a description of the location of BOOKMARK-NAME-OR-RECORD."
(bookmark-maybe-load-default-file)
- (bookmark-get-filename bookmark))
+ ;; We could call the `handler' and ask for it to construct a description
+ ;; dynamically: it would open up several new possibilities, but it
+ ;; would have the major disadvantage of forcing to load each and
+ ;; every handler when the user calls bookmark-menu.
+ (or (bookmark-prop-get bookmark-name-or-record 'location)
+ (bookmark-get-filename bookmark-name-or-record)
+ "-- Unknown location --"))
;;;###autoload
-(defun bookmark-rename (old &optional new)
- "Change the name of OLD bookmark to NEW name.
-If called from keyboard, prompt for OLD and NEW. If called from
-menubar, select OLD from a menu and prompt for NEW.
-
-Both OLD and NEW are bookmark names (strings), never bookmark records.
+(defun bookmark-rename (old-name &optional new-name)
+ "Change the name of OLD-NAME bookmark to NEW-NAME name.
+If called from keyboard, prompt for OLD-NAME and NEW-NAME.
+If called from menubar, select OLD-NAME from a menu and prompt for NEW-NAME.
-If called from Lisp, prompt for NEW if only OLD was passed as an
-argument. If called with two strings, then no prompting is done. You
-must pass at least OLD when calling from Lisp.
+If called from Lisp, prompt for NEW-NAME if only OLD-NAME was passed
+as an argument. If called with two strings, then no prompting is done.
+You must pass at least OLD-NAME when calling from Lisp.
While you are entering the new name, consecutive C-w's insert
consecutive words from the text of the buffer into the new bookmark
name."
(interactive (list (bookmark-completing-read "Old bookmark name")))
- (bookmark-maybe-historicize-string old)
+ (bookmark-maybe-historicize-string old-name)
(bookmark-maybe-load-default-file)
(setq bookmark-yank-point (point))
(setq bookmark-current-buffer (current-buffer))
- (let ((newname
- (or new ; use second arg, if non-nil
+ (let ((final-new-name
+ (or new-name ; use second arg, if non-nil
(read-from-minibuffer
"New name: "
nil
now-map)
nil
'bookmark-history))))
- (bookmark-set-name old newname)
- (setq bookmark-current-bookmark newname)
+ (bookmark-set-name old-name final-new-name)
+ (setq bookmark-current-bookmark final-new-name)
(bookmark-bmenu-surreptitiously-rebuild-list)
(setq bookmark-alist-modification-count
(1+ bookmark-alist-modification-count))
;;;###autoload
-(defun bookmark-insert (bookmark)
- "Insert the text of the file pointed to by bookmark BOOKMARK.
-BOOKMARK is a bookmark name (a string), not a bookmark record.
+(defun bookmark-insert (bookmark-name)
+ "Insert the text of the file pointed to by bookmark BOOKMARK-NAME.
+BOOKMARK-NAME is a bookmark name (a string), not a bookmark record.
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 help on function `bookmark-load' for more about
this."
(interactive (list (bookmark-completing-read "Insert bookmark contents")))
- (bookmark-maybe-historicize-string bookmark)
+ (bookmark-maybe-historicize-string bookmark-name)
(bookmark-maybe-load-default-file)
(let ((orig-point (point))
(str-to-insert
(save-current-buffer
- (bookmark-handle-bookmark bookmark)
+ (bookmark-handle-bookmark bookmark-name)
(buffer-string))))
(insert str-to-insert)
(push-mark)
;;;###autoload
-(defun bookmark-delete (bookmark &optional batch)
- "Delete BOOKMARK from the bookmark list.
-BOOKMARK is a bookmark name (a string), not a bookmark record.
+(defun bookmark-delete (bookmark-name &optional batch)
+ "Delete BOOKMARK-NAME from the bookmark list.
Removes only the first instance of a bookmark with that name. If
there are one or more other bookmarks with the same name, they will
(interactive
(list (bookmark-completing-read "Delete bookmark"
bookmark-current-bookmark)))
- (bookmark-maybe-historicize-string bookmark)
+ (bookmark-maybe-historicize-string bookmark-name)
(bookmark-maybe-load-default-file)
- (let ((will-go (bookmark-get-bookmark bookmark 'noerror)))
+ (let ((will-go (bookmark-get-bookmark bookmark-name 'noerror)))
(setq bookmark-alist (delq will-go bookmark-alist))
;; Added by db, nil bookmark-current-bookmark if the last
;; occurrence has been deleted
;;but there's no better default, and
;;I guess it's better than none at all.
"~/" bookmark-default-file 'confirm)))
- (setq file (expand-file-name file))
+ (setq file (abbreviate-file-name (expand-file-name file)))
(if (not (file-readable-p file))
(error "Cannot read bookmark file %s" file)
(if (null no-msg)
(setq bookmark-alist-modification-count
(1+ bookmark-alist-modification-count)))
(if (string-equal
- (expand-file-name bookmark-default-file)
+ (abbreviate-file-name
+ (expand-file-name bookmark-default-file))
file)
(setq bookmarks-already-loaded t))
(bookmark-bmenu-surreptitiously-rebuild-list))
(defvar bookmark-bmenu-mode-map
(let ((map (make-keymap)))
- (suppress-keymap map t)
- (define-key map "q" 'quit-window)
+ (set-keymap-parent map special-mode-map)
(define-key map "v" 'bookmark-bmenu-select)
(define-key map "w" 'bookmark-bmenu-locate)
(define-key map "2" 'bookmark-bmenu-2-window)
(define-key map "n" 'next-line)
(define-key map "p" 'previous-line)
(define-key map "\177" 'bookmark-bmenu-backup-unmark)
- (define-key map "?" 'describe-mode)
(define-key map "u" 'bookmark-bmenu-unmark)
(define-key map "m" 'bookmark-bmenu-mark)
(define-key map "l" 'bookmark-bmenu-load)
(define-key map "a" 'bookmark-bmenu-show-annotation)
(define-key map "A" 'bookmark-bmenu-show-all-annotations)
(define-key map "e" 'bookmark-bmenu-edit-annotation)
- ;; The original binding of M-g hides the M-g prefix map.
- ;; If someone has a better idea than M-g s, I'm open to suggestions.
- (define-key map [?\M-g ?s] 'bookmark-bmenu-search)
+ (define-key map "/" 'bookmark-bmenu-search)
(define-key map [mouse-2] 'bookmark-bmenu-other-window-with-mouse)
map))
(bookmark-maybe-load-default-file)
(let ((buf (get-buffer-create "*Bookmark List*")))
(if (called-interactively-p 'interactive)
- (if (or (window-dedicated-p) (window-minibuffer-p))
- (pop-to-buffer buf)
- (switch-to-buffer buf))
+ (switch-to-buffer buf)
(set-buffer buf)))
(let ((inhibit-read-only t))
(erase-buffer)
" *" " ")
name)
(setq end (point))
- (put-text-property start (+ 2 start) 'bookmark-name-prop name)
+ (put-text-property
+ (+ bookmark-bmenu-marks-width start) end 'bookmark-name-prop name)
(when (display-mouse-p)
(add-text-properties
- (+ 2 start) end
+ (+ bookmark-bmenu-marks-width start) end
'(mouse-face highlight
follow-link t
help-echo "mouse-2: go to this bookmark in other window")))
(insert "\n")))
+ (set-buffer-modified-p (not (= bookmark-alist-modification-count 0)))
(goto-char (point-min))
(forward-line 2)
(bookmark-bmenu-mode)
-(defun bookmark-bmenu-mode ()
+(define-derived-mode bookmark-bmenu-mode special-mode "Bookmark Menu"
"Major mode for editing a list of bookmarks.
Each line describes one of the bookmarks in Emacs.
Letters do not insert themselves; instead, they are commands.
in another buffer.
\\[bookmark-bmenu-show-all-annotations] -- show the annotations of all bookmarks in another buffer.
\\[bookmark-bmenu-edit-annotation] -- edit the annotation for the current bookmark."
- (kill-all-local-variables)
- (use-local-map bookmark-bmenu-mode-map)
(setq truncate-lines t)
- (setq buffer-read-only t)
- (setq major-mode 'bookmark-bmenu-mode)
- (setq mode-name "Bookmark Menu")
- (run-mode-hooks 'bookmark-bmenu-mode-hook))
+ (setq buffer-read-only t))
(defun bookmark-bmenu-toggle-filenames (&optional show)
mainly for debugging, and should not be necessary in normal use."
(if (and (not force) bookmark-bmenu-toggle-filenames)
nil ;already shown, so do nothing
- (save-excursion
- (save-window-excursion
- (goto-char (point-min))
- (forward-line 2)
- (setq bookmark-bmenu-hidden-bookmarks ())
- (let ((inhibit-read-only t))
- (while (< (point) (point-max))
- (let ((bmrk (bookmark-bmenu-bookmark)))
- (push bmrk bookmark-bmenu-hidden-bookmarks)
- (let ((start (save-excursion (end-of-line) (point))))
- (move-to-column bookmark-bmenu-file-column t)
- ;; Strip off `mouse-face' from the white spaces region.
- (if (display-mouse-p)
- (remove-text-properties start (point)
- '(mouse-face nil help-echo nil))))
- (delete-region (point) (progn (end-of-line) (point)))
- (insert " ")
- ;; Pass the NO-HISTORY arg:
- (bookmark-insert-location bmrk t)
- (forward-line 1))))))))
+ (with-buffer-modified-unmodified
+ (save-excursion
+ (save-window-excursion
+ (goto-char (point-min))
+ (forward-line 2)
+ (setq bookmark-bmenu-hidden-bookmarks ())
+ (let ((inhibit-read-only t))
+ (while (< (point) (point-max))
+ (let ((bmrk (bookmark-bmenu-bookmark)))
+ (push bmrk bookmark-bmenu-hidden-bookmarks)
+ (let ((start (line-end-position)))
+ (move-to-column bookmark-bmenu-file-column t)
+ ;; Strip off `mouse-face' from the white spaces region.
+ (if (display-mouse-p)
+ (remove-text-properties start (point)
+ '(mouse-face nil help-echo nil))))
+ (delete-region (point) (progn (end-of-line) (point)))
+ (insert " ")
+ ;; Pass the NO-HISTORY arg:
+ (bookmark-insert-location bmrk t)
+ (forward-line 1)))))))))
(defun bookmark-bmenu-hide-filenames (&optional force)
mainly for debugging, and should not be necessary in normal use."
(when (and (not force) bookmark-bmenu-toggle-filenames)
;; nothing to hide if above is nil
- (save-excursion
- (goto-char (point-min))
- (forward-line 2)
- (setq bookmark-bmenu-hidden-bookmarks
- (nreverse bookmark-bmenu-hidden-bookmarks))
- (let ((inhibit-read-only t)
- (column (save-excursion
- (goto-char (point-min))
- (search-forward "Bookmark")
- (backward-word 1)
- (current-column))))
- (while bookmark-bmenu-hidden-bookmarks
- (move-to-column column t)
- (bookmark-kill-line)
- (let ((name (pop bookmark-bmenu-hidden-bookmarks))
- (start (point)))
- (insert name)
- (if (display-mouse-p)
- (add-text-properties
- start (point)
- '(mouse-face highlight
- follow-link t
- help-echo
- "mouse-2: go to this bookmark in other window"))))
- (forward-line 1))))))
-
-
-(defun bookmark-bmenu-check-position ()
+ (with-buffer-modified-unmodified
+ (save-excursion
+ (goto-char (point-min))
+ (forward-line 2)
+ (setq bookmark-bmenu-hidden-bookmarks
+ (nreverse bookmark-bmenu-hidden-bookmarks))
+ (let ((inhibit-read-only t))
+ (while bookmark-bmenu-hidden-bookmarks
+ (move-to-column bookmark-bmenu-marks-width t)
+ (bookmark-kill-line)
+ (let ((name (pop bookmark-bmenu-hidden-bookmarks))
+ (start (point)))
+ (insert name)
+ (put-text-property start (point) 'bookmark-name-prop name)
+ (if (display-mouse-p)
+ (add-text-properties
+ start (point)
+ '(mouse-face
+ highlight follow-link t help-echo
+ "mouse-2: go to this bookmark in other window"))))
+ (forward-line 1)))))))
+
+
+(defun bookmark-bmenu-ensure-position ()
"If point is not on a bookmark line, move it to one.
-If before the first bookmark line, move it to the first.
-If after the last, move it to the last.
-Return `bookmark-alist'."
- ;; FIXME: The doc string originally implied that this returns nil if
- ;; not on a bookmark, which is false. Is there any real reason to
- ;; return `bookmark-alist'? This seems to be called in a few places
- ;; as a check of whether point is on a bookmark line. Those
- ;; "checks" are in fact no-ops, since this never returns nil.
- ;; -dadams, 2009-10-10
- (cond ((< (count-lines (point-min) (point)) 2)
+If before the first bookmark line, move to the first; if after the
+last full line, move to the last full line. The return value is undefined."
+ (cond ((< (count-lines (point-min) (point)) bookmark-bmenu-header-height)
(goto-char (point-min))
- (forward-line 2)
- bookmark-alist)
+ (forward-line bookmark-bmenu-header-height))
((and (bolp) (eobp))
- (beginning-of-line 0)
- bookmark-alist)
- (t
- bookmark-alist)))
+ (beginning-of-line 0))))
(defun bookmark-bmenu-bookmark ()
"Return the bookmark for this line in an interactive bookmark list buffer."
- (when (bookmark-bmenu-check-position)
- (get-text-property (line-beginning-position) 'bookmark-name-prop)))
+ (bookmark-bmenu-ensure-position)
+ (save-excursion
+ (beginning-of-line)
+ (forward-char bookmark-bmenu-marks-width)
+ (get-text-property (point) 'bookmark-name-prop)))
-(defun bookmark-show-annotation (bookmark)
- "Display the annotation for bookmark named BOOKMARK in a buffer,
+(defun bookmark-show-annotation (bookmark-name-or-record)
+ "Display the annotation for BOOKMARK-NAME-OR-RECORD in a buffer,
if an annotation exists."
- (let ((annotation (bookmark-get-annotation bookmark)))
- (if (and annotation (not (string-equal annotation "")))
- (save-excursion
- (let ((old-buf (current-buffer)))
- (pop-to-buffer (get-buffer-create "*Bookmark Annotation*") t)
- (delete-region (point-min) (point-max))
- ;; (insert (concat "Annotation for bookmark '" bookmark "':\n\n"))
- (insert annotation)
- (goto-char (point-min))
- (pop-to-buffer old-buf))))))
+ (let ((annotation (bookmark-get-annotation bookmark-name-or-record)))
+ (when (and annotation (not (string-equal annotation "")))
+ (save-excursion
+ (let ((old-buf (current-buffer)))
+ (pop-to-buffer (get-buffer-create "*Bookmark Annotation*") t)
+ (delete-region (point-min) (point-max))
+ (insert annotation)
+ (goto-char (point-min))
+ (switch-to-buffer-other-window old-buf))))))
(defun bookmark-show-all-annotations ()
"Mark bookmark on this line to be displayed by \\<bookmark-bmenu-mode-map>\\[bookmark-bmenu-select]."
(interactive)
(beginning-of-line)
- (if (bookmark-bmenu-check-position)
- (let ((inhibit-read-only t))
- (delete-char 1)
- (insert ?>)
- (forward-line 1)
- (bookmark-bmenu-check-position))))
+ (bookmark-bmenu-ensure-position)
+ (with-buffer-modified-unmodified
+ (let ((inhibit-read-only t))
+ (delete-char 1)
+ (insert ?>)
+ (forward-line 1)
+ (bookmark-bmenu-ensure-position))))
(defun bookmark-bmenu-select ()
"Select this line's bookmark; also display bookmarks marked with `>'.
You can mark bookmarks with the \\<bookmark-bmenu-mode-map>\\[bookmark-bmenu-mark] command."
(interactive)
- (if (bookmark-bmenu-check-position)
- (let ((bmrk (bookmark-bmenu-bookmark))
- (menu (current-buffer))
- (others ())
- tem)
- (goto-char (point-min))
- (while (re-search-forward "^>" nil t)
- (setq tem (bookmark-bmenu-bookmark))
- (let ((inhibit-read-only t))
- (delete-char -1)
- (insert ?\s))
- (or (string-equal tem bmrk)
- (member tem others)
- (setq others (cons tem others))))
- (setq others (nreverse others)
- tem (/ (1- (frame-height)) (1+ (length others))))
- (delete-other-windows)
- (bookmark-jump bmrk)
- (bury-buffer menu)
- (if others
- (while others
- (split-window nil tem)
- (other-window 1)
- (bookmark-jump (car others))
- (setq others (cdr others)))
- (other-window 1)))))
+ (let ((bmrk (bookmark-bmenu-bookmark))
+ (menu (current-buffer))
+ (others ())
+ tem)
+ (goto-char (point-min))
+ (while (re-search-forward "^>" nil t)
+ (setq tem (bookmark-bmenu-bookmark))
+ (let ((inhibit-read-only t))
+ (delete-char -1)
+ (insert ?\s))
+ (or (string-equal tem bmrk)
+ (member tem others)
+ (setq others (cons tem others))))
+ (setq others (nreverse others)
+ tem (/ (1- (frame-height)) (1+ (length others))))
+ (delete-other-windows)
+ (bookmark-jump bmrk)
+ (bury-buffer menu)
+ (if others
+ (while others
+ (split-window nil tem)
+ (other-window 1)
+ (bookmark-jump (car others))
+ (setq others (cdr others)))
+ (other-window 1))))
+
+
+(defun bookmark-bmenu-any-marks ()
+ "Return non-nil if any bookmarks are marked in the marks column."
+ (save-excursion
+ (goto-char (point-min))
+ (bookmark-bmenu-ensure-position)
+ (catch 'found-mark
+ (while (not (eobp))
+ (beginning-of-line)
+ (if (looking-at "^\\S-")
+ (throw 'found-mark t)
+ (forward-line 1)))
+ nil)))
(defun bookmark-bmenu-save (parg)
(interactive "P")
(save-excursion
(save-window-excursion
- (bookmark-save parg))))
+ (bookmark-save parg)
+ (set-buffer-modified-p nil))))
(defun bookmark-bmenu-load ()
"Load the bookmark file and rebuild the bookmark menu-buffer."
(interactive)
- (if (bookmark-bmenu-check-position)
- (save-excursion
- (save-window-excursion
- ;; This will call `bookmark-bmenu-list'
- (call-interactively 'bookmark-load)))))
+ (bookmark-bmenu-ensure-position)
+ (save-excursion
+ (save-window-excursion
+ ;; This will call `bookmark-bmenu-list'
+ (call-interactively 'bookmark-load))))
(defun bookmark-bmenu-1-window ()
"Select this line's bookmark, alone, in full frame."
(interactive)
- (if (bookmark-bmenu-check-position)
- (progn
- (bookmark-jump (bookmark-bmenu-bookmark))
- (bury-buffer (other-buffer))
- (delete-other-windows))))
+ (bookmark-jump (bookmark-bmenu-bookmark))
+ (bury-buffer (other-buffer))
+ (delete-other-windows))
(defun bookmark-bmenu-2-window ()
"Select this line's bookmark, with previous buffer in second window."
(interactive)
- (if (bookmark-bmenu-check-position)
- (let ((bmrk (bookmark-bmenu-bookmark))
- (menu (current-buffer))
- (pop-up-windows t))
- (delete-other-windows)
- (switch-to-buffer (other-buffer))
- (let ((bookmark-automatically-show-annotations nil)) ;FIXME: needed?
- (bookmark--jump-via bmrk 'pop-to-buffer))
- (bury-buffer menu))))
+ (let ((bmrk (bookmark-bmenu-bookmark))
+ (menu (current-buffer))
+ (pop-up-windows t))
+ (delete-other-windows)
+ (switch-to-buffer (other-buffer) nil t)
+ (bookmark--jump-via bmrk 'pop-to-buffer)
+ (bury-buffer menu)))
(defun bookmark-bmenu-this-window ()
"Select this line's bookmark in this window."
(interactive)
- (if (bookmark-bmenu-check-position)
- (bookmark-jump (bookmark-bmenu-bookmark))))
+ (bookmark-jump (bookmark-bmenu-bookmark)))
(defun bookmark-bmenu-other-window ()
"Select this line's bookmark in other window, leaving bookmark menu visible."
(interactive)
(let ((bookmark (bookmark-bmenu-bookmark)))
- (if (bookmark-bmenu-check-position)
- (let ((bookmark-automatically-show-annotations t)) ;FIXME: needed?
- (bookmark--jump-via bookmark 'switch-to-buffer-other-window)))))
+ (bookmark--jump-via bookmark 'switch-to-buffer-other-window)))
(defun bookmark-bmenu-switch-other-window ()
(pop-up-windows t)
same-window-buffer-names
same-window-regexps)
- (if (bookmark-bmenu-check-position)
- (let ((bookmark-automatically-show-annotations t)) ;FIXME: needed?
- (bookmark--jump-via bookmark 'display-buffer)))))
+ (bookmark--jump-via bookmark 'display-buffer)))
(defun bookmark-bmenu-other-window-with-mouse (event)
"Select bookmark at the mouse pointer in other window, leaving bookmark menu visible."
"Show the annotation for the current bookmark in another window."
(interactive)
(let ((bookmark (bookmark-bmenu-bookmark)))
- (if (bookmark-bmenu-check-position)
- (bookmark-show-annotation bookmark))))
+ (bookmark-show-annotation bookmark)))
(defun bookmark-bmenu-show-all-annotations ()
"Edit the annotation for the current bookmark in another window."
(interactive)
(let ((bookmark (bookmark-bmenu-bookmark)))
- (if (bookmark-bmenu-check-position)
- (bookmark-edit-annotation bookmark))))
+ (bookmark-edit-annotation bookmark)))
(defun bookmark-bmenu-unmark (&optional backup)
Optional BACKUP means move up."
(interactive "P")
(beginning-of-line)
- (if (bookmark-bmenu-check-position)
- (progn
- (let ((inhibit-read-only t))
- (delete-char 1)
- ;; any flags to reset according to circumstances? How about a
- ;; flag indicating whether this bookmark is being visited?
- ;; well, we don't have this now, so maybe later.
- (insert " "))
- (forward-line (if backup -1 1))
- (bookmark-bmenu-check-position))))
+ (bookmark-bmenu-ensure-position)
+ (with-buffer-modified-unmodified
+ (let ((inhibit-read-only t))
+ (delete-char 1)
+ ;; any flags to reset according to circumstances? How about a
+ ;; flag indicating whether this bookmark is being visited?
+ ;; well, we don't have this now, so maybe later.
+ (insert " "))
+ (forward-line (if backup -1 1))
+ (bookmark-bmenu-ensure-position)))
(defun bookmark-bmenu-backup-unmark ()
"Move up and cancel all requested operations on bookmark on line above."
(interactive)
(forward-line -1)
- (if (bookmark-bmenu-check-position)
- (progn
- (bookmark-bmenu-unmark)
- (forward-line -1)
- (bookmark-bmenu-check-position))))
+ (bookmark-bmenu-ensure-position)
+ (bookmark-bmenu-unmark)
+ (forward-line -1)
+ (bookmark-bmenu-ensure-position))
(defun bookmark-bmenu-delete ()
To carry out the deletions that you've marked, use \\<bookmark-bmenu-mode-map>\\[bookmark-bmenu-execute-deletions]."
(interactive)
(beginning-of-line)
- (if (bookmark-bmenu-check-position)
- (let ((inhibit-read-only t))
- (delete-char 1)
- (insert ?D)
- (forward-line 1)
- (bookmark-bmenu-check-position))))
+ (bookmark-bmenu-ensure-position)
+ (with-buffer-modified-unmodified
+ (let ((inhibit-read-only t))
+ (delete-char 1)
+ (insert ?D)
+ (forward-line 1)
+ (bookmark-bmenu-ensure-position))))
(defun bookmark-bmenu-delete-backwards ()
(interactive)
(bookmark-bmenu-delete)
(forward-line -2)
- (if (bookmark-bmenu-check-position)
- (forward-line 1))
- (bookmark-bmenu-check-position))
+ (bookmark-bmenu-ensure-position)
+ (forward-line 1)
+ (bookmark-bmenu-ensure-position))
(defun bookmark-bmenu-execute-deletions ()
- "Delete bookmarks marked with \\<Buffer-menu-mode-map>\\[Buffer-menu-delete] commands."
+ "Delete bookmarks flagged `D'."
(interactive)
(message "Deleting bookmarks...")
(let ((o-point (point))
(defun bookmark-bmenu-rename ()
"Rename bookmark on current line. Prompts for a new name."
(interactive)
- (if (bookmark-bmenu-check-position)
- (let ((bmrk (bookmark-bmenu-bookmark))
- (thispoint (point)))
- (bookmark-rename bmrk)
- (goto-char thispoint))))
+ (let ((bmrk (bookmark-bmenu-bookmark))
+ (thispoint (point)))
+ (bookmark-rename bmrk)
+ (goto-char thispoint)))
(defun bookmark-bmenu-locate ()
"Display location of this bookmark. Displays in the minibuffer."
(interactive)
- (if (bookmark-bmenu-check-position)
- (let ((bmrk (bookmark-bmenu-bookmark)))
- (message "%s" (bookmark-location bmrk)))))
+ (let ((bmrk (bookmark-bmenu-bookmark)))
+ (message "%s" (bookmark-location bmrk))))
(defun bookmark-bmenu-relocate ()
"Change the file path of the bookmark on the current line,
prompting with completion for the new path."
(interactive)
- (if (bookmark-bmenu-check-position)
- (let ((bmrk (bookmark-bmenu-bookmark))
- (thispoint (point)))
- (bookmark-relocate bmrk)
- (goto-char thispoint))))
+ (let ((bmrk (bookmark-bmenu-bookmark))
+ (thispoint (point)))
+ (bookmark-relocate bmrk)
+ (goto-char thispoint)))
;;; Bookmark-bmenu search
(tmp-list ()))
(while
(let ((char (read-key (concat prompt bookmark-search-pattern))))
- (case char
- ((?\e ?\r) nil) ; RET or ESC break the search loop.
+ (pcase char
+ ((or ?\e ?\r) nil) ; RET or ESC break the search loop.
(?\C-g (setq bookmark-quit-flag t) nil)
(?\d (pop tmp-list) t) ; Delete last char of pattern with DEL
- (t
+ (_
(if (characterp char)
(push char tmp-list)
(setq unread-command-events
(defun bookmark-bmenu-filter-alist-by-regexp (regexp)
"Filter `bookmark-alist' with bookmarks matching REGEXP and rebuild list."
(let ((bookmark-alist
- (loop for i in bookmark-alist
- when (string-match regexp (car i)) collect i into new
- finally return new)))
+ (cl-loop for i in bookmark-alist
+ when (string-match regexp (car i)) collect i into new
+ finally return new)))
(bookmark-bmenu-list)))
(defun bookmark-bmenu-goto-bookmark (name)
"Move point to bookmark with name NAME."
(goto-char (point-min))
- (bookmark-bmenu-check-position)
(while (not (equal name (bookmark-bmenu-bookmark)))
(forward-line 1))
(forward-line 0))
;;;###autoload
(defvar menu-bar-bookmark-map
(let ((map (make-sparse-keymap "Bookmark functions")))
- (define-key map [load]
- `(menu-item ,(purecopy "Load a Bookmark File...") bookmark-load
- :help ,(purecopy "Load bookmarks from a bookmark file)")))
- (define-key map [write]
- `(menu-item ,(purecopy "Save Bookmarks As...") bookmark-write
- :help ,(purecopy "Write bookmarks to a file (reading the file name with the minibuffer)")))
- (define-key map [save]
- `(menu-item ,(purecopy "Save Bookmarks") bookmark-save
- :help ,(purecopy "Save currently defined bookmarks")))
- (define-key map [edit]
- `(menu-item ,(purecopy "Edit Bookmark List") bookmark-bmenu-list
- :help ,(purecopy "Display a list of existing bookmarks")))
- (define-key map [delete]
- `(menu-item ,(purecopy "Delete Bookmark...") bookmark-delete
- :help ,(purecopy "Delete a bookmark from the bookmark list")))
- (define-key map [rename]
- `(menu-item ,(purecopy "Rename Bookmark...") bookmark-rename
- :help ,(purecopy "Change the name of a bookmark")))
- (define-key map [locate]
- `(menu-item ,(purecopy "Insert Location...") bookmark-locate
- :help ,(purecopy "Insert the name of the file associated with a bookmark")))
- (define-key map [insert]
- `(menu-item ,(purecopy "Insert Contents...") bookmark-insert
- :help ,(purecopy "Insert the text of the file pointed to by a bookmark")))
- (define-key map [set]
- `(menu-item ,(purecopy "Set Bookmark...") bookmark-set
- :help ,(purecopy "Set a bookmark named inside a file.")))
- (define-key map [jump]
- `(menu-item ,(purecopy "Jump to Bookmark...") bookmark-jump
- :help ,(purecopy "Jump to a bookmark (a point in some file)")))
+ (bindings--define-key map [load]
+ '(menu-item "Load a Bookmark File..." bookmark-load
+ :help "Load bookmarks from a bookmark file)"))
+ (bindings--define-key map [write]
+ '(menu-item "Save Bookmarks As..." bookmark-write
+ :help "Write bookmarks to a file (reading the file name with the minibuffer)"))
+ (bindings--define-key map [save]
+ '(menu-item "Save Bookmarks" bookmark-save
+ :help "Save currently defined bookmarks"))
+ (bindings--define-key map [edit]
+ '(menu-item "Edit Bookmark List" bookmark-bmenu-list
+ :help "Display a list of existing bookmarks"))
+ (bindings--define-key map [delete]
+ '(menu-item "Delete Bookmark..." bookmark-delete
+ :help "Delete a bookmark from the bookmark list"))
+ (bindings--define-key map [rename]
+ '(menu-item "Rename Bookmark..." bookmark-rename
+ :help "Change the name of a bookmark"))
+ (bindings--define-key map [locate]
+ '(menu-item "Insert Location..." bookmark-locate
+ :help "Insert the name of the file associated with a bookmark"))
+ (bindings--define-key map [insert]
+ '(menu-item "Insert Contents..." bookmark-insert
+ :help "Insert the text of the file pointed to by a bookmark"))
+ (bindings--define-key map [set]
+ '(menu-item "Set Bookmark..." bookmark-set
+ :help "Set a bookmark named inside a file."))
+ (bindings--define-key map [jump]
+ '(menu-item "Jump to Bookmark..." bookmark-jump
+ :help "Jump to a bookmark (a point in some file)"))
map))
;;;###autoload
\f
;; Load Hook
(defvar bookmark-load-hook nil
- "Hook run at the end of loading bookmark.")
+ "Hook run at the end of loading library `bookmark.el'.")
;; Exit Hook, called from kill-emacs-hook
+(define-obsolete-variable-alias 'bookmark-exit-hooks
+ 'bookmark-exit-hook "22.1")
(defvar bookmark-exit-hook nil
"Hook run when Emacs exits.")
-(define-obsolete-variable-alias 'bookmark-exit-hooks 'bookmark-exit-hook "22.1")
-
(defun bookmark-exit-hook-internal ()
"Save bookmark state, if necessary, at Emacs exit time.
This also runs `bookmark-exit-hook'."
(bookmark-time-to-save-p t)
(bookmark-save)))
-(add-hook 'kill-emacs-hook 'bookmark-exit-hook-internal)
+(unless noninteractive
+ (add-hook 'kill-emacs-hook 'bookmark-exit-hook-internal))
(defun bookmark-unload-function ()
"Unload the Bookmark library."
(provide 'bookmark)
-;; arch-tag: 139f519a-dd0c-4b8d-8b5d-f9fcf53ca8f6
;;; bookmark.el ends here