whose calling discipline HANDLER-FUNC should of course match.")
-(defvar bookmarks-already-loaded nil)
+(defvar bookmarks-already-loaded nil
+ "Non-nil iff bookmarks have been loaded from `bookmark-default-file'.")
;; more stuff added by db.
"Length of the context strings recorded on either side of a bookmark.")
-(defvar bookmark-current-point 0)
-(defvar bookmark-yank-point 0)
-(defvar bookmark-current-buffer nil)
+(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.")
+
+
+(defvar bookmark-yank-point 0
+ "The next point from which to pull source text for `bookmark-yank-word'.
+This point is in `bookmark-curent-buffer'.")
+
-(defvar Info-suffix-list)
\f
;; Helper functions.
(bookmark-maybe-load-default-file)
- (setq bookmark-current-point (point))
(setq bookmark-yank-point (point))
(setq bookmark-current-buffer (current-buffer))
(bookmark-store str (cdr record) no-overwrite)
;; Ask for an annotation buffer for this bookmark
- (if bookmark-use-annotations
- (bookmark-edit-annotation str)
- (goto-char bookmark-current-point)))))
+ (when bookmark-use-annotations
+ (bookmark-edit-annotation str)))))
(defun bookmark-kill-line (&optional newline-too)
"Kill from point to end of line.
(let ((annotation (buffer-substring-no-properties (point-min) (point-max)))
(bookmark bookmark-annotation-name))
(bookmark-set-annotation bookmark annotation)
- (bookmark-bmenu-surreptitiously-rebuild-list)
- (goto-char bookmark-current-point))
+ (bookmark-bmenu-surreptitiously-rebuild-list))
(kill-buffer (current-buffer)))
(defun bookmark-insert-current-bookmark ()
- "Insert this buffer's value of `bookmark-current-bookmark'.
-Default to file name if it's nil."
+ "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
(defun bookmark-yank-word ()
- "Get the next word from the buffer and append it to the name of the
-bookmark currently being set, advancing point by one word."
+ "Get the next word from buffer `bookmark-current-buffer' and append
+it to the name of the bookmark currently being set, advancing
+`bookmark-yank-point' by one word."
(interactive)
(let ((string (with-current-buffer bookmark-current-buffer
(goto-char bookmark-yank-point)
;;;###autoload
-(defun bookmark-jump (bookmark)
+(defun bookmark-jump (bookmark &optional display-func)
"Jump to bookmark BOOKMARK (a point in some file).
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
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."
+the latter is usually only used 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 other value
+would be, e.g., `switch-to-buffer-other-window'."
(interactive
(list (bookmark-completing-read "Jump to bookmark"
bookmark-current-bookmark)))
(unless bookmark
(error "No bookmark specified"))
(bookmark-maybe-historicize-string bookmark)
- (bookmark--jump-via bookmark 'switch-to-buffer))
+ (bookmark--jump-via bookmark (or display-func 'switch-to-buffer)))
;;;###autoload
(defun bookmark-jump-other-window (bookmark)
"Jump to BOOKMARK in another window. See `bookmark-jump' for more."
(interactive
- (let ((bkm (bookmark-completing-read "Jump to bookmark (in another window)"
- bookmark-current-bookmark)))
- (if (> emacs-major-version 21)
- (list bkm) bkm)))
- (when bookmark
- (bookmark-maybe-historicize-string bookmark)
- (bookmark--jump-via bookmark 'switch-to-buffer-other-window)))
-
-
-(defun bookmark-file-or-variation-thereof (file)
- "Return FILE (a string) if it exists, or return a reasonable
-variation of FILE if that exists. Reasonable variations are checked
-by appending suffixes defined in `Info-suffix-list'. If cannot find FILE
-nor a reasonable variation thereof, then still return FILE if it can
-be retrieved from a VC backend, else return nil."
- (if (file-exists-p file)
- file
- (or
- (progn (require 'info) ; ensure Info-suffix-list is bound
- (catch 'found
- (mapc (lambda (elt)
- (let ((suffixed-file (concat file (car elt))))
- (if (file-exists-p suffixed-file)
- (throw 'found suffixed-file))))
- Info-suffix-list)
- nil))
- ;; Last possibility: try VC
- (if (vc-backend file) file))))
+ (list (bookmark-completing-read "Jump to bookmark (in another window)"
+ bookmark-current-bookmark)))
+ (bookmark-jump bookmark 'switch-to-buffer-other-window))
+
(defun bookmark-jump-noselect (bookmark)
"Return the location pointed to by the bookmark BOOKMARK.
(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'.
-BOOKMARK may be a bookmark name (a string) or a bookmark record."
+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.
+"
(condition-case err
(funcall (or (bookmark-get-handler bookmark)
'bookmark-default-handler)
;; 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 either be a bookmark name (found in
- ;; `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))
- ;; If file is not a directory, this should be a no-op.
- (display-name (directory-file-name file)))
+ ;; `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 file ;Don't know how to relocate if there's no `file'.
- (ding)
- ;; Dialog boxes can accept a file target, but usually don't
- ;; know how to accept a directory target (at least, this
- ;; was true in Gnome on GNU/Linux, and Bug#4230 says it's
- ;; true on Windows as well). Thus, suppress file dialogs
- ;; when relocating.
- (let ((use-dialog-box nil)
- (use-file-dialog nil))
- (if (y-or-n-p (concat display-name " nonexistent. Relocate \""
- bookmark "\"? "))
- (progn
- (bookmark-relocate bookmark)
- ;; Try again.
- (funcall (or (bookmark-get-handler bookmark)
- 'bookmark-default-handler)
- (bookmark-get-bookmark bookmark)))
- (message
- "Bookmark not relocated; consider removing it \(%s\)." bookmark)
- (signal (car err) (cdr err)))))))))
+ ;; If file is not a dir, directory-file-name just returns file.
+ (let ((display-name (directory-file-name file)))
+ (ding)
+ ;; Dialog boxes can accept a file target, but usually don't
+ ;; know how to accept a directory target (at least, this
+ ;; is true in Gnome on GNU/Linux, and Bug#4230 says it's
+ ;; true on Windows as well). So we suppress file dialogs
+ ;; when relocating.
+ (let ((use-dialog-box nil)
+ (use-file-dialog nil))
+ (if (y-or-n-p (concat display-name " nonexistent. Relocate \""
+ bookmark "\"? "))
+ (progn
+ (bookmark-relocate bookmark)
+ ;; Try again.
+ (funcall (or (bookmark-get-handler bookmark)
+ 'bookmark-default-handler)
+ (bookmark-get-bookmark bookmark)))
+ (message
+ "Bookmark not relocated; consider removing it \(%s\)."
+ bookmark)
+ (signal (car err) (cdr err))))))))))
;; Added by db.
(when (stringp bookmark)
(setq bookmark-current-bookmark bookmark))
nil)
+(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)")
+
(defun bookmark-default-handler (bmk-record)
"Default handler to jump to a particular bookmark location.
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)))
- ;; FIXME: bookmark-file-or-variation-thereof was needed for Info files,
- ;; but now that Info bookmarks are handled elsewhere it seems that we
- ;; should be able to get rid of it. --Stef
- (if (not (if buf (buffer-live-p buf)
- (setq file (bookmark-file-or-variation-thereof file))))
- (signal 'file-error
- `("Jumping to bookmark" "No such file or directory"
- (bookmark-get-filename bmk-record)))
- (set-buffer (or buf (find-file-noselect file)))
+ (let ((file (bookmark-get-filename bmk-record))
+ (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
(defalias 'bookmark-locate 'bookmark-insert-location)
(defun bookmark-location (bookmark)
- "Return the name of the file associated with 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."
(bookmark-maybe-load-default-file)
(bookmark-get-filename bookmark))
(bookmark-maybe-historicize-string old)
(bookmark-maybe-load-default-file)
- (setq bookmark-current-point (point))
(setq bookmark-yank-point (point))
(setq bookmark-current-buffer (current-buffer))
(let ((newname
;; occurrence has been deleted
(or (bookmark-get-bookmark bookmark-current-bookmark 'noerror)
(setq bookmark-current-bookmark nil)))
- ;; Don't rebuild the list
- (if batch
- nil
- (bookmark-bmenu-surreptitiously-rebuild-list)
- (setq bookmark-alist-modification-count
- (1+ bookmark-alist-modification-count))
- (if (bookmark-time-to-save-p)
- (bookmark-save))))
+ (unless batch
+ (bookmark-bmenu-surreptitiously-rebuild-list))
+ (setq bookmark-alist-modification-count
+ (1+ bookmark-alist-modification-count))
+ (when (bookmark-time-to-save-p)
+ (bookmark-save)))
(defun bookmark-time-to-save-p (&optional final-time)
(forward-char o-col))
(goto-char o-point))
(beginning-of-line)
- (setq bookmark-alist-modification-count
- (1+ bookmark-alist-modification-count))
- (if (bookmark-time-to-save-p)
- (bookmark-save))
(message "Deleting bookmarks...done")
))
(let ((bmrk (bookmark-bmenu-bookmark))
(thispoint (point)))
(bookmark-rename bmrk)
- (bookmark-bmenu-list)
(goto-char thispoint))))
;;;###autoload
(defvar menu-bar-bookmark-map
(let ((map (make-sparse-keymap "Bookmark functions")))
- (define-key map [load] '("Load a Bookmark File..." . bookmark-load))
- (define-key map [write] '("Save Bookmarks As..." . bookmark-write))
- (define-key map [save] '("Save Bookmarks" . bookmark-save))
- (define-key map [edit] '("Edit Bookmark List" . bookmark-bmenu-list))
- (define-key map [delete] '("Delete Bookmark..." . bookmark-delete))
- (define-key map [rename] '("Rename Bookmark..." . bookmark-rename))
- (define-key map [locate] '("Insert Location..." . bookmark-locate))
- (define-key map [insert] '("Insert Contents..." . bookmark-insert))
- (define-key map [set] '("Set Bookmark..." . bookmark-set))
- (define-key map [jump] '("Jump to Bookmark..." . bookmark-jump))
+ (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)")))
map))
;;;###autoload