rudolfochrist / interleave

Emacs minor mode to interleave notes and text books

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

invalid function when used with pdf-tools

bricewge opened this issue · comments

I got hit by a issue already reported here politza/pdf-tools#210 when using interleave with pdf-tools. Here is the trace:

Debugger entered--Lisp error: (invalid-function pdf-view-current-page)
  pdf-view-current-page()
  #[nil "\300 \207" [pdf-view-current-page] 1]()
  interleave-add-note()
  funcall-interactively(interleave-add-note)
  call-interactively(interleave-add-note nil nil)
  command-execute(interleave-add-note)

Sorry, but I cannot reproduce this error. I see in the referenced issues that you're using an older version of interleave. Can you please update to the latest version check if the error still occurs and report back. Thanks.

Best,
Sebastain

I didn't participated in the referenced issue. I'm using interleave 20160825.953 together with pdf-tools 20160525.920 which are the latest versions available for both package on MELPA.
Can I do anything to help you reproduce the bug ?

Whoops, sorry. Somehow I was under impression you and the other OP were the same person. Stupid me.

Anyway, can you describe the exact steps you do that results into this error? And a github gist of your interleave and pdf-tools configuration, if possible. Thanks.

Here are the instruction on how to reproduce it, with emacs 25.1.1 execute emacs -Q and evaluate the following:

(require 'package)
(setq package-archives '(("melpa" . "https://melpa.org/packages/")))
(package-initialize)
(package-refresh-contents)
(package-install 'interleave)
(package-install 'pdf-tools)
(require 'interleave)
(require 'pdf-tools)
(pdf-tools-install)
(find-file "/tmp/test.org")

Then do M-x interleave ~/test.pdf where the pdf is this one. You can now see two buffers side-by-side, the org-mode one on the right and the pdf-tools one on the left where you can type i or interleave-add-note to trigger the bug I got bitten by.

I found the problem, but there are good and bad news. The bad news is that we have to change how interleave uses DocView/pdf-tools and I'd like to wait till PR #30 is merged into master. This will hopefully be in ca. two weeks. The good news is that there is a quick fix available. If you install and require the pdf-tools before your install interleave than it works. So basically instead of doing

(package-install 'interleave)
(package-install 'pdf-tools)
(require 'interleave)
(require 'pdf-tools)

you do

(package-install 'pdf-tools)
(require 'pdf-tools)
;;; and then
(package-install 'interleave)
(require 'interleave)

Please uninstall interleave first before running the above snippet. Package.el needs to recompile interleave.


The problem was the byte compilation of the lambda expressions we use to wrap the macros doc-view-current-page and pdf-view-current-page. DocView doesn't state a problem since it is bundled with Emacs and should already be loaded before we hit interleave. If the pdf tools aren't loaded and package.el (or manually) byte compiles interleave, it also byte compiles the (lambda () (pdf-view-current-page)), even though it is in an eval-after-load block (I assume this is right. It says eval after load not compile after load). Since the byte compiler doesn't know about the pdf-view-current-page macro, it doesn't expand it and leaves it there as a function call, as you can see here:

#[nil "\300 \207" [pdf-view-current-page] 1]()

When the pdf-tools are loaded before interleave gets compiled the same lambda is compiled to:

#[nil "\300\301\302\"\207"
      [image-mode-window-get page nil]
      3]

This leaves us some options on how we'd like to address this:

  1. Use a different technique as eval-after-load. Maybe checks with fboundp etc.
  2. Use our own macros that expand in checking code.
  3. Let the user explicitly declare the he/she wants to use pdf-tools like so (e.g.)
    (setq interleave-use-pdf-tools t)
    We switch than to pdf-tools at run-time.

Nice, the workaround is definitely working. It'll do until it is fixed.
Thanks @rudolfochrist! (:

The workaround should not be needed. If you delete the package and reinstall the package, do you still get that error (without the workaround). I believe that somehow you have older .elc file from the time when that one pdf-tools macro was defined as function as mistake.

If you delete the package and reinstall the package, If you delete the package and reinstall the package

That is the workaround, isn't it? If we use the elisp from above, installing interleave, installing pdf-tools, requiring both, then delete and reinstall interleave does a byte-compile with the correct macroexpansion of pdf-view-current-page.

I can reproduce this error on a fresh Ubuntu with a fresh Emacs and fresh melpa installations.

I believe that this line is causing the issue:

(declare-function pdf-view-current-page "pdf-view.el")

pdf-view-current-page is a macro, not a function. I had commented that line out in my fork. My I missed checking that in your commit.


Deleting that line, re-byte-compiling interleave.el, and evaluating the new interleave.elc fixes this issue for me.

Sorry,
this doesn't help either. When I remove that line, byte-compile interleave and then install pdf-tools the same error occurs to me. And this is exactly the problem. We compile interleave against missing dependencies. I think the only solution is to document that if someone wants to use pdf-toolswith interleave he/she has to install it before he/she installs interleave.

Some solutions to this bug after more investigations:

  1. Document that in order to use pdf-tools it has to be installed prior to interleave. Document that interleave has to be reinstalled if pdf-tools are added.
  2. Declare pdf-tools as dependency even if the user wants to use doc-view.
  3. Reimplement doc-view-current-page/pdf-view-current-page as interleave-current-page
  4. Use (eval '(pdf-view-current-page)).

I tend to option 3 but perhaps I give it a nap before I take some action.