假设我在 evince 中打开了一个 pdf 文件(比如/path/to/my/file.pdf
从 LaTeX 生成),并且想要/path/to/my/file.tex
在我的 emacs 编辑器中打开相应的 LaTeX 源文件 ( ),我单击 evince 中的属性并将文件的路径复制到剪贴板,然后粘贴从 emacsfind-file
对话到迷你缓冲区,手动将文件结尾 pdf 更改为 tex 并打开该文件。
现在我想问是否有一种更快的方法来做同样的事情(也许使用另一个pdf查看器),例如通过配置键盘快捷键(例如在pdf查看器本身或在wm级别,在我的例子中) xmonad)或在 pdf 查看器中配置自定义按钮。
编辑我要补充一点,我需要它的情况是,我同时打开了20个pdf文档。
编辑2根据@meuh的建议,我尝试了以下方法
cat get_tex_name.sh
#!/bin/sh
pid=xprop _NET_WM_PID
filename=ls -l /proc/'$pid'/fd/ | grep pdf | sed 's/.*\(\/.*home.*\).pdf/\1tex/'
#emacsclient -c $filename
urxvt -hold -e sh -c "echo $filename"
在我的.xmonad
文件中:
[...]
-- find corresponding tex file
, ((modm, xK_p ), spawn "get_tex_name.sh")
现在,如果我有一个聚焦的 evince 实例并通过 Windows-p 运行 stript,它似乎无法获取文件名(我认为是因为 xprop 似乎没有返回聚焦窗口的 pid,但只有在单击它之后才返回) 。
那么如何让它发挥作用呢?
答案1
有许多工具可用于自动执行此操作。当然,首先考虑的可能是在 emacs 中查看 pdf 文件,它可以做到这一点。然后您就可以通过 elisp 访问文件名并对其进行操作。
在 emacs 之外,您可以使用,例如,
pgrep -xa evince
查找 evince 的进程 ID 和命令行,然后提取启动时使用的文件名。或者,如果您在证据中交互地选择了文件,则可以使用
ls -l /proc/"$pid"/fd/
(其中 pid 来自之前的pgrep
)查看打开了哪些文件描述符,然后选择以pdf
, 结尾的文件描述符来获取 pdf 文件的名称。
如果您有多个正在运行的证据,您可以使用
xprop _NET_WM_PID
以交互方式单击给定窗口,并获取该程序的进程 ID。不幸的是,evince 没有将完整的文件名放入 X11 属性中。
要将文件名传递给 emacs,请在 emacs 中emacsclient
执行后使用。(server-start)
要为组合脚本设置键绑定,请参阅xmonad。
这是一个可能的 bash 脚本
#!/bin/bash
pid=$(xprop _NET_WM_PID | sed -n '/not found/q; s/.* //; p')
if [ -z "$pid" ]
then echo "no pid"; exit 1
fi
filename=$(ls -l /proc/"$pid"/fd/ |
sed -n '/pdf$/{ s/.* -> //; s/pdf$/tex/; p}')
if [ -z "$filename" ]
then echo "no filename"; exit 2
fi
emacsclient -c -n "$filename"