vedang / pdf-tools

Emacs support library for PDF files.
https://pdftools.wiki
GNU General Public License v3.0
641 stars 90 forks source link

Bookmark error when opening a pdf with pdf-tools #4

Open ghost opened 3 years ago

ghost commented 3 years ago

If I bookmark a PDF with bookmark+, I am getting this error when I try to open it:

pdf-info--normalize-file-or-buffer: Buffer is not associated with any file *Bookmark List*

And the file does not open.

This error only occurs with pdf-tools, and not if I bookmark the file with doc-view.

Here is the backtrace error.

Debugger entered--Lisp error: (error "Buffer is not associated with any file :*Bookmark ...")
  signal(error ("Buffer is not associated with any file :*Bookmark ..."))
  error("Buffer is not associated with any file :%s" "*Bookmark List*")
  pdf-info--normalize-file-or-buffer(nil)
  pdf-info-number-of-pages()
  pdf-cache-number-of-pages()
  pdf-view-goto-page(687)
  pdf-view-bookmark-after-jump-hook()
  run-hooks(bookmark-after-jump-hook)
  (let ((orig-buff (current-buffer))) (run-hooks 'bookmark-after-jump-hook))
  (catch 'bookmark--jump-via (bookmark-handle-bookmark bookmark) (if (and bmkp-use-w32-browser-p (fboundp 'w32-browser) (bookmark-get-filename bookmark)) nil (let ((win (get-buffer-window (current-buffer) 0))) (if win (progn (set-window-point win (point))))) (if (and (bmkp-autonamed-bookmark-for-buffer-p bookmark (buffer-name)) (not bmkp-use-w32-browser-p)) (progn (setq bookmark (bmkp-update-autonamed-bookmark bookmark)))) (let* ((temp (and (boundp 'bmkp-auto-light-when-jump) bmkp-auto-light-when-jump))) (cond ((eql temp 'autonamed-bookmark) (if (bmkp-autonamed-bookmark-p bookmark) (progn (bmkp-light-bookmark bookmark nil nil nil ...)))) ((eql temp 'non-autonamed-bookmark) (if (bmkp-autonamed-bookmark-p bookmark) nil (bmkp-light-bookmark bookmark nil nil nil 'USE-POINT))) ((eql temp 'any-bookmark) (bmkp-light-bookmark bookmark nil nil nil 'USE-POINT)) ((eql temp 'autonamed-in-buffer) (bmkp-light-bookmarks (bmkp-remove-if-not #'bmkp-autonamed-bookmark-p (bmkp-this-buffer-alist-only)) nil 'MSG)) ((eql temp 'non-autonamed-in-buffer) (bmkp-light-bookmarks (bmkp-remove-if #'bmkp-autonamed-bookmark-p (bmkp-this-buffer-alist-only)) nil 'MSG)) ((eql temp 'all-in-buffer) (bmkp-light-this-buffer nil 'MSG))))) (let ((orig-buff (current-buffer))) (run-hooks 'bookmark-after-jump-hook)) (let ((jump-fn (bmkp-get-tag-value bookmark "bmkp-jump"))) (if jump-fn (progn (funcall jump-fn)))) (if bookmark-automatically-show-annotations (progn (bookmark-show-annotation bookmark))))
  bookmark--jump-via((#("common-order-1994.pdf" 0 21 (bmkp-full-record #1)) (filename . "~/resources/liturgy/common-order-1994.pdf") (buffer-name . "common-order-1994.pdf") (visits . 2) (time 24664 3208 45415 0) (created 24663 35208 782 0) (position . 1) (page . 687) (slice) (size . fit-page) (origin 0.0 . 0.0) (handler . pdf-view-bookmark-jump-handler)) bmkp--pop-to-buffer-same-window)
  (let ((bmkp-use-region (if flip-use-region-p (not bmkp-use-region) bmkp-use-region))) (bookmark--jump-via bookmark display-function))
  bmkp-jump-1(#("common-order-1994.pdf" 0 21 (bmkp-full-record (#1 (filename . "~/resources/liturgy/common-order-1994.pdf") (buffer-name . "common-order-1994.pdf") (visits . 2) (time 24664 3208 45415 0) (created 24663 35208 782 0) (position . 1) (page . 687) (slice) (size . fit-page) (origin 0.0 . 0.0) (handler . pdf-view-bookmark-jump-handler)))) bmkp--pop-to-buffer-same-window nil)
  (let ((bookmark-name (bookmark-bmenu-bookmark))) (bmkp-jump-1 bookmark-name 'bmkp--pop-to-buffer-same-window flip-use-region-p))
  bookmark-bmenu-this-window(nil)
  funcall-interactively(bookmark-bmenu-this-window nil)
  call-interactively(bookmark-bmenu-this-window nil nil)
  command-execute(bookmark-bmenu-this-window)
  read-from-minibuffer("M-x " nil (keymap (10 . minibuffer-complete-and-exit) (13 . minibuffer-complete-and-exit) keymap (C-tab . switch-to-completions) (menu-bar keymap (minibuf "Minibuf" keymap (tab menu-item "Complete" minibuffer-complete :help "Complete as far as possible") (space menu-item "Complete Word" minibuffer-complete-word :help "Complete at most one word") (63 menu-item "List Completions" minibuffer-completion-help :help "Display all possible completions") "Minibuf")) (27 keymap (118 . switch-to-completions)) (prior . switch-to-completions) (63 . minibuffer-completion-help) (32 . minibuffer-complete-word) (9 . minibuffer-complete) keymap (menu-bar keymap (minibuf "Minibuf" keymap (previous menu-item "Previous History Item" previous-history-element :help "Put previous minibuffer history element in the min...") (next menu-item "Next History Item" next-history-element :help "Put next minibuffer history element in the minibuf...") (isearch-backward menu-item "Isearch History Backward" isearch-backward :help "Incrementally search minibuffer history backward") (isearch-forward menu-item "Isearch History Forward" isearch-forward :help "Incrementally search minibuffer history forward") (return menu-item "Enter" exit-minibuffer :key-sequence "\15" :help "Terminate input and exit minibuffer") (quit menu-item "Quit" abort-recursive-edit :help "Abort input and exit minibuffer") "Minibuf")) (10 . exit-minibuffer) (13 . exit-minibuffer) (7 . minibuffer-keyboard-quit) (C-tab . file-cache-minibuffer-complete) (9 . self-insert-command) (XF86Back . previous-history-element) (up . previous-line-or-history-element) (prior . previous-history-element) (XF86Forward . next-history-element) (down . next-line-or-history-element) (next . next-history-element) (27 keymap (60 . minibuffer-beginning-of-buffer) (114 . previous-matching-history-element) (115 . next-matching-history-element) (112 . previous-history-element) (110 . next-history-element))) nil extended-command-history nil nil)
  completing-read-default("M-x " #f(compiled-function (string pred action) #<bytecode 0x84015c2b41>) commandp t nil extended-command-history nil nil)
  completing-read("M-x " #f(compiled-function (string pred action) #<bytecode 0x84015c2b41>) commandp t nil extended-command-history)
  read-extended-command()
  byte-code("\302\30\11\303 \10E)\207" [execute-extended-command--last-typed current-prefix-arg nil read-extended-command] 3)
  call-interactively(execute-extended-command nil nil)
  command-execute(execute-extended-command)

I contacted the developer of bookmark+ about this first and this was his response:

As I said, I don't use (or have) pdf-tools, thus pdf-info--normalize-file-or-buffer etc. All of what appears to be problematic happens in pdf-tools code, starting with pdf-view-bookmark-after-jump-hook. I know nothing about that hook or pdf-view or pdf-cache or pdf-info*. This is your bookmark: ("common-order-1994.pdf" (filename . "~/resources/liturgy/common-order-1994.pdf") (buffer-name . "common-order-1994.pdf") (visits . 2) (time 24664 3208 45415 0) (created 24663 35208 782 0) (position . 1) (page . 687) (slice) (size . fit-page) (origin 0.0 . 0.0) (handler . pdf-view-bookmark-jump-handler))

That function is what's causing the problem. It sounds like it maybe expects some context that isn't established when it's invoked. It apparently tried to use the buffer that was current when you tried to jump to the bookmark (Bookmark List) as if it was a PDF file buffer (?).

The only fields in your bookmark that Bookmark+ knows about are filename, buffer-name, visits, time, created, position, and handler. All the other fields are no doubt defined and created by pdf-tools, pdf-view, pdf-cache, or pdf-info.

I suggest you follow up with the maintainers of those libraries. (None of those libraries are in vanilla Emacs, at least through Emacs 27.)

vedang commented 3 years ago

Thanks for reporting this here. I'll look into this over the next weekend and share an update.

chriad commented 1 month ago

I also use bookmark+ and my workaround is to change the handler from pdf-view-bookmark-jump-handler to pdf-view-bookmark-jump. I do not complely understand the hook, but anyway pdf-view-bookmark-jump-handler is called by pdf-view-bookmark-jump so this should be the correct entry point in the pdf-view-make-record function.

At the moment I patch it with el-patch like this:

(el-patch-defun pdf-view-bookmark-make-record  (&optional no-page no-slice no-size no-origin)
      ;; TODO: add NO-PAGE, NO-SLICE, NO-SIZE, NO-ORIGIN to the docstring.
      "Create a bookmark PDF record.

The optional, boolean args exclude certain attributes."
      (let ((displayed-p (eq (current-buffer)
                             (window-buffer))))
        (cons (buffer-name)
              (append (bookmark-make-record-default nil t 1)
                      `(,(unless no-page
                           (cons 'page (pdf-view-current-page)))
                        ,(unless no-slice
                           (cons 'slice (and displayed-p (pdf-view-current-slice))))
                        ,(unless no-size
                           (cons 'size pdf-view-display-size))
                        ,(unless no-origin
                           (cons 'origin
                                 (and displayed-p
                                      (let ((edges (pdf-util-image-displayed-edges nil t)))
                                        (pdf-util-scale-pixel-to-relative
                                         (cons (car edges) (cadr edges)) nil t)))))
                        (handler . (el-patch-swap pdf-view-bookmark-jump-handler pdf-view-bookmark-jump)))))))