大家是如何使用 git 安装 pdf-tools 的?

看了 b 站金色飞贼小米的教程也希望配置一下 pdf-tools。但是安装的过程实 在不算顺利,现在也没有安装好。希望了解一下大家在不使用包管理器的情况下 安装 pdf-tools 都遇到了什么困难,是如何解决的。

我遇到的困难

  1. 未安装 cask shell make: cask: No such file or directory make: *** [Makefile:49: .cask/30.1] Error 127 安装 cask,后仍然无效, 原因是系统找不到 cask,我的 PATH 里面默认没有 .local/bin 于是添 加之后,完成了 make -s,tar 文件也有了。

  2. 无法安装 tar根据官网提示可以使用两种方法

    • make install-package 这个方法行不通
      make: *** No rule to make target 'install-package'.  Stop.
      
    • 于是转向在 Emacs 中执行命令 M-x package-install-file RET pdf-tools-${VERSION}.tar RET 结果再次出现依赖问题。shell package-compute-transaction: Package ‘tablist’ (version 1.0) is unavailable 前往安装了 tablist,也尝试 require tablist,在 Emacs 的确能够找到 tablist 的命令,但是尝试安装 tar 文件的时候, 仍然出现一样的错误,在 pdf-tools 的 issuse 里面没有找到类似的问题, 我也不知道如何排查,现在止步于此。

系统信息

  • system: Debian 13 testing
  • DE: xfce
  • Emacs: 30.1

不是有 pdf-tools-install 命令可以直接调用吗?你的意思是打算所有依赖包包括 poppler 之类的都不靠 apt-install 全靠自己安装?

我的做法:

  1. magit 往 .emacs.d 中添加 pdf-tools 的 submodule 并添加到 load-path 中:

    ;; 可以使用 lazy-cat 配置中的 `add-subdirs-to-load-path' 
    ;; https://github.com/manateelazycat/lazycat-emacs/blob/master/site-start.el
    (add-to-list 'load-path "path/to/pdf-tools" t) 
    
  2. 手动 require 依赖 (如果不用 use-package 的话)

    (require 'pdf-tools)
    (require 'pdf-occur)
    (require 'pdf-history)
    (require 'pdf-links)
    (require 'pdf-outline)
    (require 'pdf-annot)
    (require 'pdf-sync)
    
    (pdf-tools-install)
    

我的意思是依赖使用 git pull 下来,现在执行到官网的一个安装的步骤,出现了一个依赖问题


就是这个 make -s 之后,使用官网的推荐的两个方法,都出现了问题。

  1. 使用第一个方法
pdf-tools on  master [?]
❯ ls
appveyor.yml  COPYING.SYNCTEX  pdf-tools-1.1.0.entry  README.org
Cask	     lisp	      pdf-tools-1.1.0.tar    server
ci	     Makefile	      pdf-tools-readme.txt   test
COPYING       NEWS	      README		     TODO.org

pdf-tools on  master [?]
❯ make install-package
Loading /etc/emacs/site-start.d/00debian.el (source)...
Loading /etc/emacs/site-start.d/50autoconf.el (source)...
Loading /etc/emacs/site-start.d/50dictionaries-common.el (source)...
Using Emacs 30.1
Loading /etc/emacs/site-start.d/00debian.el (source)...
Loading /etc/emacs/site-start.d/50autoconf.el (source)...
Loading /etc/emacs/site-start.d/50dictionaries-common.el (source)...
Loading /etc/emacs/site-start.d/00debian.el (source)...
Loading /etc/emacs/site-start.d/50autoconf.el (source)...
Loading /etc/emacs/site-start.d/50dictionaries-common.el (source)...
Loading /etc/emacs/site-start.d/00debian.el (source)...
Loading /etc/emacs/site-start.d/50autoconf.el (source)...
Loading /etc/emacs/site-start.d/50dictionaries-common.el (source)...
make: *** No rule to make target 'install-package'.  Stop.

pdf-tools on  master [?]
❯
  1. 使用 Emacs 内置的方法
string-match-p: Package ‘tablist’ (version 1.0) is unavailable

直接使用 git 就可以了吗?不需要按照官网的方法编译吗

难绷,pdf-tools的readme没更新,那个make target早没了,我看了一眼,应该是先 make all再make melpa-package生成一个压缩文件,然后再用emacs M-x package-install-file 安装这个压缩文件。另外 tablist这个emas包要手动安装一下。

是的, 缺啥依赖就下载啥依赖

(估计还得加 tablist)

(官网的 Readme 应该如上所说是过期的)

你把 pdf-tools 的路径加到 emacs 的 load-path 里 直接调用 pdf-tools-install 命令就行了。不用手动编译。

如果报缺 tablist 的错误就把 tablist 先于 pdf-tools 加到 load-path 里

我现在就是卡在了安装这个压缩文件的步骤,尽管我安装了 tablist,安装的时候仍然报错

string-match-p: Package ‘tablist’ (version 1.0) is unavailable

此外我是使用 make -s 生成的压缩包。tablist 就是使用 git clone 下来,然后在配置里面引用。(我习惯在测试的时候使用 git clone 然后稳定了在使用 submodule 再配置一次)

我也尝试过这样,

  (require 'tablist)

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

  (provide init-pdf-tools)

load-path 是借鉴的 centaur Emacs 的方法。

下面是报错信息

Debugger entered--Lisp error: (void-function pdf-occur-global-minor-mode)
  (pdf-occur-global-minor-mode 1)
  (progn (pdf-occur-global-minor-mode 1))
  (if (memq 'pdf-occur-global-minor-mode pdf-tools-enabled-modes) (progn (pdf-occur-global-minor-mode 1)))
  pdf-tools-install-noverify()
  (if (or (pdf-info-running-p) (condition-case nil (progn (pdf-info-check-epdfinfo) t) (error nil))) (pdf-tools-install-noverify) (let ((target-directory (or (and (stringp pdf-info-epdfinfo-program) (file-name-directory pdf-info-epdfinfo-program)) pdf-tools-directory))) (if (or no-query-p (y-or-n-p "Need to (re)build the epdfinfo program, do it now ?")) (pdf-tools-build-server target-directory skip-dependencies-p force-dependencies-p #'(lambda (executable) (let (...) (if ... ... ... ... ...)))) (message "PDF Tools not activated"))))
  pdf-tools-install()
  load-with-code-conversion("/home/kazure/.emacs.d/test-lisp/lisp/init-pdf-tools.el" "/home/kazure/.emacs.d/test-lisp/lisp/init-pdf-tools.el" nil t)
  require(init-pdf-tools)
  load-with-code-conversion("/home/kazure/.emacs.d/test-lisp/lisp/init-test.el" "/home/kazure/.emacs.d/test-lisp/lisp/init-test.el" nil t)
  require(init-test)
  load-with-code-conversion("/home/kazure/.emacs.d/init.el" "/home/kazure/.emacs.d/init.el" t t)
  load("/home/kazure/.emacs.d/init" noerror nomessage)
  #f(compiled-function () #<bytecode 0x90c5f07d5a11391>)()
  #f(compiled-function () #<bytecode -0x4307d7bb01d2857>)()
  handler-bind-1(#f(compiled-function () #<bytecode -0x4307d7bb01d2857>) (error) startup--debug)
  startup--load-user-init-file(#f(compiled-function () #<bytecode -0x1349f088e6ae632>) #f(compiled-function () #<bytecode 0x731968ef8c7b19b>) t)
  command-line()
  normal-top-level()

官方的 README 提示了依赖,但是尽管我下载了这个依赖,仍然这样报错。

不过这个报错方式我也是第一次见,之前的报错都是在使用 debug-init 之后可以看到,require 了什么包,然后没找到。

是不行的, 需要同时引用其他 pdf-tools 的依赖:

(require 'pdf-tools)
(require 'pdf-occur)
(require 'pdf-history)
(require 'pdf-links)
(require 'pdf-outline)
(require 'pdf-annot)
(require 'pdf-sync)

这样应该就可以 (pdf-tools-install) 了.

(无密集恐惧症可以试试下面的最小可复现代码:

emacs -q --eval "(add-to-list 'load-path \"~/.emacs.d/lisp/extensions/tablist/\")" --eval "(add-to-list 'load-path \".emacs.d/lisp/extensions/pdf-tools/lisp/\")" --eval "(require 'pdf-tools)" --eval "(require 'pdf-occur)" --eval "(require 'pdf-history)" --eval "(require 'pdf-links)" --eval "(require 'pdf-outline)" --eval "(require 'pdf-annot)" --eval "(require 'pdf-sync)" --eval "(pdf-tools-install)"

原来是这样,奇怪为什么没有写在官方的文档里面

总结

  1. get pdf-tools, 然后执行这个命令 /path/to/pdf-tools/server/autobuild
  2. 把 tablist 依赖放到 load-path 里面。
  3. 配置 init.el
(require 'pdf-tools)

(require 'pdf-occur)
(require 'pdf-history)
(require 'pdf-links)
(require 'pdf-outline)
(require 'pdf-annot)
(require 'pdf-sync)

(pdf-tools-install)
  1. 这个时候就可以使用了,但是你会发现 tablist 会报错,这个无伤大雅,但是如果和我一样觉得有点难受,那么可以修改一下 tablist.el,实际上就是给原来没有声明赋值的对象声明一下。
    (define-minor-mode tablist-minor-mode
      ""
      :init-value nil
      :lighter nil
      :keymap nil
      :interactive nil
    
      (unless (derived-mode-p 'tabulated-list-mode)
        (error "Buffer is not in Tabulated List Mode"))
      (tablist-init (not tablist-minor-mode)))
    
      ;; ......
    
      (define-minor-mode tablist-edit-column-minor-mode
        ""
        :init-value nil
        :lighter nil
        :keymap nil
        :interactive nil
        ;; .....
    

我是在一个 issue 里面翻到的 (忘了在哪里找到的💦)

官方貌似比较推荐使用 use-package 来自动解决依赖的 require?

他是因为是自己用 git 手动安装的。用 git 手动安装就没有办法自动处理作者写的 autoload。

如果他用任意的一个包管理器,比如 straight 或者 package.el,都能够处理好作者写好的 autoload,从而在(作者认为)需要的时候自动加载需要的包。这样就只需要掉用 emacs 的命令 pdf-tools-install 就好了。别的什么都不需要。

用 git 装包的也可以考虑看一下 borg,能够处理用 git 手动安装的包来生成对应的 autoload。