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:
- Use a different technique as
eval-after-load
. Maybe checks withfboundp
etc. - Use our own macros that expand in checking code.
- 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 topdf-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-tools
with interleave
he/she has to install it before he/she installs interleave.
Some solutions to this bug after more investigations:
- Document that in order to use
pdf-tools
it has to be installed prior tointerleave
. Document thatinterleave
has to be reinstalled ifpdf-tools
are added. - Declare pdf-tools as dependency even if the user wants to use
doc-view
. - Reimplement
doc-view-current-page
/pdf-view-current-page
asinterleave-current-page
- Use
(eval '(pdf-view-current-page))
.
I tend to option 3 but perhaps I give it a nap before I take some action.