问题
我的 Emacs 中既安装了 pdf-tools,也有安装 eaf-pdf-browser。
并且设置 blink-search-grep-pdf-backend:
(setq blink-search-grep-pdf-backend 'pdf-tools)
默认使用 pdf-tools 预览 blink-search 搜索的结果。
但是在实际使用中出现错误,如下:
Debugger entered--Lisp error: (error "Buffer is not associated with any file :PDF")
error("Buffer is not associated with any file :%s" "PDF")
pdf-info--normalize-file-or-buffer(nil)
pdf-info-number-of-pages()
pdf-cache-number-of-pages()
pdf-view-goto-page(1)
blink-search-grep-pdf-pdftool-goto("/Users/c/Library/Mobile Documents/iCloud~QReader~M..." 1 "D1080")
(cond ((and (eq blink-search-grep-pdf-backend 'pdf-tools) (featurep 'pdf-tools)) (blink-search-grep-pdf-pdftool-goto file page submatches)) ((and (eq blink-search-grep-pdf-backend 'eaf-pdf-viewer) (featurep 'eaf-pdf-viewer)) (eaf-pdf-jump-to-page file page)) (t (message "Unknown backend %s" blink-search-grep-pdf-backend)))
blink-search-grep-pdf-do("/Users/c/Library/Mobile Documents/iCloud~QReader~M..." 1 "D1080")
(let ((match-file (blink-search-grep-file-get-match-buffer file))) (blink-search-grep-pdf-do file page submatches) (if match-file nil (add-to-list 'blink-search-grep-file-temp-buffers (current-buffer))))
(progn (select-window input-window) (blink-search-preview-select-window) (let ((match-file (blink-search-grep-file-get-match-buffer file))) (blink-search-grep-pdf-do file page submatches) (if match-file nil (add-to-list 'blink-search-grep-file-temp-buffers (current-buffer)))) (select-window input-window))
(if input-window (progn (select-window input-window) (blink-search-preview-select-window) (let ((match-file (blink-search-grep-file-get-match-buffer file))) (blink-search-grep-pdf-do file page submatches) (if match-file nil (add-to-list 'blink-search-grep-file-temp-buffers (current-buffer)))) (select-window input-window)))
(when input-window (select-window input-window) (blink-search-preview-select-window) (let ((match-file (blink-search-grep-file-get-match-buffer file))) (blink-search-grep-pdf-do file page submatches) (if match-file nil (add-to-list 'blink-search-grep-file-temp-buffers (current-buffer)))) (select-window input-window))
(let* ((inhibit-message t) (input-window (get-buffer-window blink-search-input-buffer))) (when input-window (select-window input-window) (blink-search-preview-select-window) (let ((match-file (blink-search-grep-file-get-match-buffer file))) (blink-search-grep-pdf-do file page submatches) (if match-file nil (add-to-list 'blink-search-grep-file-temp-buffers (current-buffer)))) (select-window input-window)))
(blink-search-select-input-window (let ((match-file (blink-search-grep-file-get-match-buffer file))) (blink-search-grep-pdf-do file page submatches) (if match-file nil (add-to-list 'blink-search-grep-file-temp-buffers (current-buffer)))))
blink-search-grep-pdf-real-preview("/Users/c/Library/Mobile Documents/iCloud~QReader~M..." 1 "D1080")
(closure ((submatches . "D1080") (page . 1) (file . "/Users/c/Library/Mobile Documents/iCloud~QReader~M...") t) nil (blink-search-grep-pdf-real-preview file page submatches))()
apply((closure ((submatches . "D1080") (page . 1) (file . "/Users/c/Library/Mobile Documents/iCloud~QReader~M...") t) nil (blink-search-grep-pdf-real-preview file page submatches)) nil)
timer-event-handler([t 0 0 500000 nil (closure ((submatches . "D1080") (page . 1) (file . "/Users/c/Library/Mobile Documents/iCloud~QReader~M...") t) nil (blink-search-grep-pdf-real-preview file page submatches)) nil idle 0 nil])
这个错误栈是 blink-search-grep-pdf-pdftool-goto
中 pdf-view-goto-page(1)
函数抛出的。
(defun blink-search-grep-pdf-pdftool-goto (file page submatches)
(find-file file)
(pdf-view-goto-page page)
(let ((matches (pdf-isearch-search-page submatches)))
(pdf-isearch-hl-matches (nth 0 matches) matches t)))
因为实际上我要预览的 PDF 是被 eaf-pdf-browser 打开,并不是 pdf-tools 打开,我猜测是 eaf-pdf-browser 拦截了 blink-search-grep-pdf-pdftool-goto
的 find-file
?我看到 eaf 源代码中:
(defun eaf--find-file-advisor (orig-fn file &rest args)
"Advisor of `find-file' that opens EAF supported file using EAF.
It currently identifies PDF, videos, images, and mindmap file extensions."
(let ((fn (if (commandp 'eaf-open)
#'(lambda (file)
(eaf-open file))
orig-fn))
(ext (file-name-extension file)))
(if (eaf--find-file-ext-p ext)
(apply fn file nil)
(apply orig-fn file args))))
(advice-add #'find-file :around #'eaf--find-file-advisor)
我将 eaf-pdf-extension-list
识别的拓展名列表将 PDF 格式删除 (setq eaf-pdf-extension-list '("xps" "oxps" "cbz" "epub" "fb2" "fbz"))
:
eaf-pdf-extension-list is a variable defined in `eaf-pdf-viewer.el'.
Its value is ("xps" "oxps" "cbz" "epub" "fb2" "fbz")
Original value was
("pdf" "xps" "oxps" "cbz" "epub" "fb2" "fbz")
这样 blink-search 就能利用 pdf-tools 预览,不会被 eaf-pdf-browser 拦截。
需求
但是我除了预览,其他情形下希望使用 eaf-pdf-browser 查看 PDF,但是因为将 PDF 拓展名删除了,eaf-open
命令无法打开 PDF 格式文件了:
if: [EAF] File /Users/c/Downloads/SSM/737-678_YUN_SSM_D280A242_TD/PDF/00___006.PDF cannot be opened.
方案
该如何解决这种冲突?在调用 blink-search-grep-pdf-do
:
(defun blink-search-grep-pdf-do (file page submatches)
;;highlight the matches
(cond
((and (eq blink-search-grep-pdf-backend 'pdf-tools) (featurep 'pdf-tools))
(blink-search-grep-pdf-pdftool-goto file page submatches))
((and (eq blink-search-grep-pdf-backend 'eaf-pdf-viewer) (featurep 'eaf-pdf-viewer))
(eaf-pdf-jump-to-page file page))
;; TODO support other pdf backends
(t (message "Unknown backend %s" blink-search-grep-pdf-backend))))
前临时将 find-file 关于 eaf-pdf-browser 的 advice 删除,执行完后重新加回来? 还是有其他更优雅的方案?