下面这段代码解决了以上问题。
功能是:判断这个文件在不在zotero库里。如果在,则用zotero打开。如果不在,则用evince打开。emacs里面不会再用pdf-viewer-mode打开了。
直接粘在init文件里应该就可以用。这将替换emacs里所有pdf打开的方式。
evince也可以按需要替换成其他的软件。
(defun expand-tilde (path)
"Expand tilde in PATH to user's home directory."
(if (string-prefix-p "~" path)
(concat (getenv "HOME") (substring path 1))
path))
(defun open-pdf-in-zotero-or-evince (pdf-path)
"Open the PDF file at PDF-PATH in Zotero if it is in a Zotero storage directory, otherwise use Evince."
(setq pdf-path (expand-tilde pdf-path))
(if (string-match "/storage/" pdf-path)
(let* ((pdf-name (file-name-nondirectory pdf-path))
(pdf-dir (file-name-directory pdf-path))
(parent-dir (file-name-nondirectory (directory-file-name pdf-dir)))
(grandparent-dir (file-name-nondirectory (directory-file-name (file-name-directory pdf-dir))))
(zotero-path (concat "zotero://open-pdf/library/items/" grandparent-dir "/" parent-dir "/" pdf-name)))
(async-start-process "open-zotero" "open" nil zotero-path))
(async-start-process "open-evince" "evince" nil pdf-path)))
(defun my-find-file-advice (orig-fun &rest args)
"Advice function around ORIG-FUN to open PDFs in Zotero or Evince."
(let ((file (car args)))
(if (string-equal (file-name-extension file) "pdf")
(open-pdf-in-zotero-or-evince file)
(apply orig-fun args))))
(advice-add 'find-file :around #'my-find-file-advice)