Subject: bug#20152: 24.4: bookmarks display wrong annotation (FIX INCLUDED)

From: Boruch Baum <[email-masked]>
Date: Fri, 20 Mar 2015 06:38:54 -0400

In the bookmark list buffer, after viewing an annotation for a
bookmark, navigating to another bookmark entry does not kill the
annotation buffer display, leading to confusion about which entry
the still-visible annotation refers.

The atttached bugfix kills the annotation buffer on navigation,
and remaps navigation keys accordingly.

The bugfix also introduces an option to automatically display
annotations as one navigates within the bookmark list buffer.

The bugfix also introduces an option to toggle auto-display of
annotations.

Note that the code has two sets of key-binding definitions: Only
the first, (defvar bookmark-bmenu-mode-map ..., is for the bugfix
to bookmark.el. The second, (eval-after-load "bookmark" ..., or
better, just (progn ..., is included for convenience / testing.

;-------------------------------------------------------------------
; bookmark-bmenu-next-line
; bookmark-bmenu-previous-line
; bookmark-bmenu-forward-char
; bookmark-bmenu-backward-char
;
; Functions to address bug in which the `*Bookmark Annotation*' buffer
; is not modified or updated when navigating through the
; bookmark-bmenu-list.
;
; Also provides option to auto-display annotations as one navigates
; the bmenu-list

(defvar bookmark-bmenu-auto-display-annotations nil
"Whether to automatically display a bookmark's annotation as one
navigates through the bookmark list. `t' for yes. Default is
`nil'.")

(defun bookmark-bmenu-next-line (&optional ARG TRY-VSCROLL)
"Move cursor vertically down ARG lines within the bookmark list.
Refer to function `next-line' for details."
  (interactive "^p\np")
  (let
    ((annotation-buffer
       (get-buffer "*Bookmark Annotation*")))
    (when annotation-buffer
      (kill-buffer annotation-buffer)))
  (next-line ARG TRY-VSCROLL)
  (when bookmark-bmenu-auto-display-annotations
     (bookmark-bmenu-show-annotation)))

(defun bookmark-bmenu-previous-line (&optional ARG TRY-VSCROLL)
"Move cursor vertically up ARG lines within the bookmark list.
Refer to function `previous-line' for details."
  (interactive "^p\np")
  (let
    ((annotation-buffer
       (get-buffer "*Bookmark Annotation*")))
    (when annotation-buffer
      (kill-buffer annotation-buffer)))
  (previous-line ARG TRY-VSCROLL)
  (when bookmark-bmenu-auto-display-annotations
     (bookmark-bmenu-show-annotation)))

(defun bookmark-bmenu-forward-char (&optional N)
  (interactive "p")
  (bookmark-bmenu-backward-forward-char 'forward-char N))

(defun bookmark-bmenu-backward-char (&optional N)
  (interactive "p")
  (bookmark-bmenu-backward-forward-char 'backward-char N))

(defun bookmark-bmenu-backward-forward-char (direction-function N)
  (let (annotation-buffer
        (initial-line (line-number-at-pos)))
    (funcall direction-function N)
    (when (/= initial-line (line-number-at-pos))
      (when (setq annotation-buffer (get-buffer "*Bookmark Annotation*"))
        (kill-buffer annotation-buffer))
      (when bookmark-bmenu-auto-display-annotations
        (bookmark-bmenu-show-annotation)))))

;-------------------------------------------------------------------
;
; ONLY ONE OF THE FOLLOWING TWO OPTIONS ARE NECESSARY !
;
; Either redine the mode map, or just the individual keys
;
;-------------------------------------------------------------------
(defvar bookmark-bmenu-mode-map
  (let ((map (make-keymap)))
    (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 "1" 'bookmark-bmenu-1-window)
    (define-key map "j" 'bookmark-bmenu-this-window)
    (define-key map "\C-c\C-c" 'bookmark-bmenu-this-window)
    (define-key map "f" 'bookmark-bmenu-this-window)
    (define-key map "\C-m" 'bookmark-bmenu-this-window)
    (define-key map "o" 'bookmark-bmenu-other-window)
    (define-key map "\C-o" 'bookmark-bmenu-switch-other-window)
    (define-key map "s" 'bookmark-bmenu-save)
    (define-key map "k" 'bookmark-bmenu-delete)
    (define-key map "\C-d" 'bookmark-bmenu-delete-backwards)
    (define-key map "x" 'bookmark-bmenu-execute-deletions)
    (define-key map "d" 'bookmark-bmenu-delete)
    (define-key map " " 'bookmark-bmenu-next-line)
    (define-key map "n" 'bookmark-bmenu-next-line)
    (define-key map [remap next-line] 'bookmark-bmenu-next-line)
    (define-key map "p" 'bookmark-bmenu-previous-line)
    (define-key map [remap previous-line] 'bookmark-bmenu-previous-line)
    (define-key map "\177" 'bookmark-bmenu-backup-unmark)
    (define-key map "u" 'bookmark-bmenu-unmark)
    (define-key map "m" 'bookmark-bmenu-mark)
    (define-key map "l" 'bookmark-bmenu-load)
    (define-key map "r" 'bookmark-bmenu-rename)
    (define-key map "R" 'bookmark-bmenu-relocate)
    (define-key map "t" 'bookmark-bmenu-toggle-filenames)
    (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)
    (define-key map "/" 'bookmark-bmenu-search)
    (define-key map [remap backward-char] 'bookmark-bmenu-backward-char)
    (define-key map [remap forward-char]  'bookmark-bmenu-forward-char)
    (define-key map [mouse-2] 'bookmark-bmenu-other-window-with-mouse)
    map))

(eval-after-load "bookmark"
  (progn
    (define-key bookmark-bmenu-mode-map
      [remap next-line] 'bookmark-bmenu-next-line)
    (define-key bookmark-bmenu-mode-map
      [remap previous-line] 'bookmark-bmenu-previous-line)
    (define-key bookmark-bmenu-mode-map
      (kbd "n")   'bookmark-bmenu-next-line)
    (define-key bookmark-bmenu-mode-map
      (kbd "SPC") 'bookmark-bmenu-next-line)
    (define-key bookmark-bmenu-mode-map
      (kbd "p")   'bookmark-bmenu-previous-line)
    (define-key bookmark-bmenu-mode-map
      [remap backward-char] 'bookmark-bmenu-backward-char)
    (define-key bookmark-bmenu-mode-map
      [remap forward-char]  'bookmark-bmenu-forward-char)
  ))
;-------------------------------------------------------------------

;-------------------------------------------------------------------
; Modification to function `bookmark-bmenu-show-annotation' to allow
; for toggling whether to autodisplay annotations as one navigates
; through the bookmark list.
;
; Do note that the documentation for function `called-interactively-p'
; discourages its use in favor of eg. '(not (or executing-kbd-macro
; noninteractive))'. See there for details.
;
(defvar bookmark-bmenu-toggle-auto-display-annotations nil
"When not `nil', function `bookmark-bmenu-show-annotation' (by
default, bound to `a`), toggles whether to automatically display
a bookmark's annotation as one navigates through the bookmark
list. Default is `nil'.")

(defun bookmark-bmenu-show-annotation ()
  "Show the annotation for the current bookmark in another window."
  (interactive)
  (when (and (called-interactively-p "any")
             bookmark-bmenu-toggle-auto-display-annotations)
    (if bookmark-bmenu-auto-display-annotations
      (setq bookmark-bmenu-auto-display-annotations nil)
     (setq bookmark-bmenu-auto-display-annotations t)))
  (let ((bookmark (bookmark-bmenu-bookmark)))
    (bookmark-show-annotation bookmark)))
;-------------------------------------------------------------------

-- 
hkp://keys.gnupg.net
CA45 09B5 5351 7C11 A9D1  7286 0036 9E45 1595 8BC0