Offer non-overwrite bookmark setter (Bug#15746)

* lisp/bookmark.el (bookmark-set-internal): New helper function to do
  what `bookmark-set' used to do, but with more choices for overwrite
  vs push, and with minor changes to the interactive prompt format.
  (bookmark-set): Rewrite as wrapper around above.
  If overwriting, inform the user of that in the prompt.
  (bookmark-set-no-overwrite): New function, also done as wrapper.
  Bind to "M" in `ctl-x-r-map' autoloads.
  (bookmark-map): Similarly bind "M" here.
This commit is contained in:
Karl Fogel 2015-11-08 14:16:43 -05:00
parent 2ce0c0674e
commit 3812e17978

View file

@ -196,6 +196,7 @@ A non-nil value may result in truncated bookmark names."
;;;###autoload (define-key ctl-x-r-map "b" 'bookmark-jump)
;;;###autoload (define-key ctl-x-r-map "m" 'bookmark-set)
;;;###autoload (define-key ctl-x-r-map "M" 'bookmark-set-no-overwrite)
;;;###autoload (define-key ctl-x-r-map "l" 'bookmark-bmenu-list)
;;;###autoload
@ -204,6 +205,7 @@ A non-nil value may result in truncated bookmark names."
;; Read the help on all of these functions for details...
(define-key map "x" 'bookmark-set)
(define-key map "m" 'bookmark-set) ;"m"ark
(define-key map "M" 'bookmark-set-no-overwrite) ;"M"aybe mark
(define-key map "j" 'bookmark-jump)
(define-key map "g" 'bookmark-jump) ;"g"o
(define-key map "o" 'bookmark-jump-other-window)
@ -755,30 +757,19 @@ This expects to be called from `point-min' in a bookmark file."
map))
;;;###autoload
(defun bookmark-set (&optional name no-overwrite)
"Set a bookmark named NAME at the current location.
If name is nil, then prompt the user.
(defun bookmark-set-internal (prompt name overwrite-or-push)
"Interactively set a bookmark named NAME at the current location.
With a prefix arg (non-nil NO-OVERWRITE), do not overwrite any
existing bookmark that has the same name as NAME, but instead push the
new bookmark onto the bookmark alist. The most recently set bookmark
with name NAME is thus the one in effect at any given time, but the
others are still there, should the user decide to delete the most
recent one.
Begin the interactive prompt with PROMPT, followed by a space, a
generated default name in parentheses, a colon and a space.
To yank words from the text of the buffer and use them as part of the
bookmark name, type C-w while setting a bookmark. Successive C-w's
yank successive words.
Typing C-u inserts (at the bookmark name prompt) the name of the last
bookmark used in the document where the new bookmark is being set;
this helps you use a single bookmark name to track progress through a
large document. If there is no prior bookmark for this document, then
C-u inserts an appropriate name based on the buffer or file.
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.)"
If OVERWRITE-OR-PUSH is nil, then error if there is already a
bookmark named NAME; if `overwrite', then replace any existing
bookmark if there is one; if `push' then push the new bookmark
onto the bookmark alist. The `push' behavior means that among
bookmarks named NAME, this most recently set one becomes the one in
effect, but the others are still there, in order, if the topmost one
is ever deleted."
(interactive (list nil current-prefix-arg))
(unwind-protect
(let* ((record (bookmark-make-record))
@ -807,12 +798,24 @@ the list of bookmarks.)"
(let ((str
(or name
(read-from-minibuffer
(format "Set bookmark (%s): " default)
(format "%s (default: \"%s\"): " prompt default)
nil
bookmark-minibuffer-read-name-map
nil nil defaults))))
(and (string-equal str "") (setq str default))
(bookmark-store str (cdr record) no-overwrite)
(cond
((eq overwrite-or-push nil)
(if (bookmark-get-bookmark str t)
(error "A bookmark named \"%s\" already exists." str)
(bookmark-store str (cdr record) nil)))
((eq overwrite-or-push 'overwrite)
(bookmark-store str (cdr record) nil))
((eq overwrite-or-push 'push)
(bookmark-store str (cdr record) t))
(t
(error "Unrecognized value for `overwrite-or-push': %S"
overwrite-or-push)))
;; Ask for an annotation buffer for this bookmark
(when bookmark-use-annotations
@ -821,6 +824,66 @@ the list of bookmarks.)"
(setq bookmark-current-buffer nil)))
(defun bookmark-set (&optional name no-overwrite)
"Set a bookmark named NAME at the current location.
If NAME is nil, then prompt the user.
With a prefix arg (non-nil NO-OVERWRITE), do not overwrite any
existing bookmark that has the same name as NAME, but instead push the
new bookmark onto the bookmark alist. The most recently set bookmark
with name NAME is thus the one in effect at any given time, but the
others are still there, should the user decide to delete the most
recent one.
To yank words from the text of the buffer and use them as part of the
bookmark name, type C-w while setting a bookmark. Successive C-w's
yank successive words.
Typing C-u inserts (at the bookmark name prompt) the name of the last
bookmark used in the document where the new bookmark is being set;
this helps you use a single bookmark name to track progress through a
large document. If there is no prior bookmark for this document, then
C-u inserts an appropriate name based on the buffer or file.
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.)"
(interactive (list nil current-prefix-arg))
(let ((prompt
(if no-overwrite "Set bookmark" "Set bookmark unconditionally")))
(bookmark-set-internal prompt name (if no-overwrite 'push 'overwrite))))
(defun bookmark-set-no-overwrite (&optional name push-bookmark)
"Set a bookmark named NAME at the current location.
If NAME is nil, then prompt the user.
If a bookmark named NAME already exists and prefix argument
PUSH-BOOKMARK is non-nil, then push the new bookmark onto the
bookmark alist. Pushing it means that among bookmarks named
NAME, this one becomes the one in effect, but the others are
still there, in order, and become effective again if the user
ever deletes the most recent one.
Otherwise, if a bookmark named NAME already exists but PUSH-BOOKMARK
is nil, raise an error.
To yank words from the text of the buffer and use them as part of the
bookmark name, type C-w while setting a bookmark. Successive C-w's
yank successive words.
Typing C-u inserts (at the bookmark name prompt) the name of the last
bookmark used in the document where the new bookmark is being set;
this helps you use a single bookmark name to track progress through a
large document. If there is no prior bookmark for this document, then
C-u inserts an appropriate name based on the buffer or file.
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.)"
(interactive (list nil current-prefix-arg))
(bookmark-set-internal "Set bookmark" name (if push-bookmark 'push nil)))
(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.