;;; Code:
(require 'pp)
+(require 'text-property-search)
(eval-when-compile (require 'cl-lib))
;;; Misc comments:
"Non-nil means show annotations when jumping to a bookmark."
:type 'boolean)
+(defconst bookmark-bmenu-buffer "*Bookmark List*"
+ "Name of buffer used for Bookmark List.")
+
(defcustom bookmark-bmenu-use-header-line t
"Non-nil means to use an immovable header line.
This is as opposed to inline text at the top of the buffer."
(when (and newline-too (= (following-char) ?\n))
(delete-char 1))))
-
-;; Defvars to avoid compilation warnings:
(defvar bookmark-annotation-name nil
- "Variable holding the name of the bookmark.
-This is used in `bookmark-edit-annotation' to record the bookmark
-whose annotation is being edited.")
+ "Name of bookmark under edit in `bookmark-edit-annotation-mode'.")
+(make-variable-buffer-local 'bookmark-annotation-name)
+(defvar bookmark--annotation-from-bookmark-list nil
+ "If non-nil, `bookmark-edit-annotation-mode' should return to bookmark list.")
+(make-variable-buffer-local 'bookmark--annotation-from-bookmark-list)
(defun bookmark-default-annotation-text (bookmark-name)
"Return default annotation text for BOOKMARK-NAME.
(define-derived-mode bookmark-edit-annotation-mode
text-mode "Edit Bookmark Annotation"
"Mode for editing the annotation of bookmarks.
-When you have finished composing, type \\[bookmark-send-annotation].
+When you have finished composing, type \\[bookmark-send-edited-annotation].
\\{bookmark-edit-annotation-mode-map}")
(forward-line 1)))
;; Take no chances with text properties.
(let ((annotation (buffer-substring-no-properties (point-min) (point-max)))
- (bookmark-name bookmark-annotation-name))
+ (bookmark-name bookmark-annotation-name)
+ (from-bookmark-list bookmark--annotation-from-bookmark-list)
+ (old-buffer (current-buffer)))
(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)))
+ (message "Annotation updated for \"%s\"" bookmark-name)
+ (quit-window)
+ (bookmark-bmenu-surreptitiously-rebuild-list)
+ (when from-bookmark-list
+ (pop-to-buffer (get-buffer bookmark-bmenu-buffer))
+ (goto-char (point-min))
+ (text-property-search-forward 'bookmark-name-prop bookmark-name))
+ (kill-buffer old-buffer)))
-(defun bookmark-edit-annotation (bookmark-name-or-record)
- "Pop up a buffer for editing bookmark BOOKMARK-NAME-OR-RECORD's annotation."
+(defun bookmark-edit-annotation (bookmark-name-or-record &optional from-bookmark-list)
+ "Pop up a buffer for editing bookmark BOOKMARK-NAME-OR-RECORD's annotation.
+If optional argument FROM-BOOKMARK-LIST is non-nil, return to the
+bookmark list when editing is done."
(pop-to-buffer (generate-new-buffer-name "*Bookmark Annotation Compose*"))
(bookmark-insert-annotation bookmark-name-or-record)
(bookmark-edit-annotation-mode)
- (set (make-local-variable 'bookmark-annotation-name)
- bookmark-name-or-record))
+ (setq bookmark--annotation-from-bookmark-list from-bookmark-list)
+ (setq bookmark-annotation-name bookmark-name-or-record))
(defun bookmark-buffer-name ()
(progress-reporter-done reporter)))))
\f
-;;; Code supporting the dired-like bookmark menu.
+;;; Code supporting the dired-like bookmark list.
;; Prefix is "bookmark-bmenu" for "buffer-menu":
-
(defvar bookmark-bmenu-hidden-bookmarks ())
(defun bookmark-bmenu-surreptitiously-rebuild-list ()
"Rebuild the Bookmark List if it exists.
Don't affect the buffer ring order."
- (if (get-buffer "*Bookmark List*")
+ (if (get-buffer bookmark-bmenu-buffer)
(save-excursion
(save-window-excursion
(bookmark-bmenu-list)))))
deletion, or > if it is flagged for displaying."
(interactive)
(bookmark-maybe-load-default-file)
- (let ((buf (get-buffer-create "*Bookmark List*")))
+ (let ((buf (get-buffer-create bookmark-bmenu-buffer)))
(if (called-interactively-p 'interactive)
(switch-to-buffer buf)
(set-buffer buf)))
"Edit the annotation for the current bookmark in another window."
(interactive)
(let ((bookmark (bookmark-bmenu-bookmark)))
- (bookmark-edit-annotation bookmark)))
+ (bookmark-edit-annotation bookmark t)))
(defun bookmark-bmenu-unmark (&optional backup)
;; 3. bookmark-set-internal
(should-error (bookmark-set-internal "foo" "bar" t))))))
+(ert-deftest bookmark-tests-set/bookmark-use-annotations-t ()
+ (with-bookmark-test-file
+ (let ((bookmark-use-annotations t))
+ (save-window-excursion
+ (switch-to-buffer buffer)
+ ;; Should jump to edit annotation buffer
+ (bookmark-set "foo")
+ (should (equal major-mode 'bookmark-edit-annotation-mode))
+ ;; Should return to the original buffer
+ (bookmark-send-edited-annotation)
+ (should (equal (current-buffer) buffer))))))
+
(ert-deftest bookmark-tests-kill-line ()
(with-temp-buffer
(insert "foobar\n")
(list bookmark-tests-bookmark
(cons "name<2>" (cdr bookmark-tests-bookmark))))))))
-;; TODO: Add tests for bookmark-bmenu.
+;; TODO: Add more tests for bookmark-bmenu.
+
+(defmacro with-bookmark-bmenu-test (&rest body)
+ "Create environment for testing `bookmark-bmenu-list' and evaluate BODY.
+Same as `with-bookmark-test' but with additions suitable for
+testing `bookmark-bmenu-list'."
+ `(with-bookmark-test
+ (let ((bookmark-bmenu-buffer "*Bookmark List - Testing*"))
+ (unwind-protect
+ (save-window-excursion
+ (bookmark-bmenu-list)
+ ,@body)
+ (kill-buffer bookmark-bmenu-buffer)))))
+
+(ert-deftest bookmark-bmenu.enu-edit-annotation/show-annotation ()
+ (with-bookmark-bmenu-test
+ (bookmark-set-annotation "name" "foo")
+ (bookmark-bmenu-edit-annotation)
+ (should (string-match "foo" (buffer-string)))
+ (kill-buffer (current-buffer))))
+
+(ert-deftest bookmark-bmenu-send-edited-annotation ()
+ (with-bookmark-bmenu-test
+ (bookmark-bmenu-edit-annotation)
+ (insert "foo")
+ (bookmark-send-edited-annotation)
+ (should (equal (bookmark-get-annotation "name") "foo"))))
+
+(ert-deftest bookmark-bmenu-send-edited-annotation/restore-focus ()
+ "Test for https://debbugs.gnu.org/20150 ."
+ (with-bookmark-bmenu-test
+ (bookmark-bmenu-edit-annotation)
+ (insert "foo")
+ (bookmark-send-edited-annotation)
+ (should (equal (buffer-name (current-buffer)) bookmark-bmenu-buffer))
+ (should (looking-at "name"))))
(provide 'bookmark-tests)
;;; bookmark-tests.el ends here