0

Suppose I have opened a pdf file (say /path/to/my/file.pdf generated from LaTeX) in evince and want to open the corresponding LaTeX source file (/path/to/my/file.tex) in my emacs editor, I click on properties in evince and copy the path to the file to the clipboard, paste it to the minibuffer from emacs find-file dialogue, manually change the file ending pdf to tex and open the file.

Now I want to ask if there is a significantly faster way to do the same thing (maybe using another pdf-viewer), for example by configuring a keyboard shortcut (for example in the pdf-viewer itself or on wm level, in my case xmonad) or configuring a custom button in the pdf viewer.

Edit I should add that the situation where I need it is, that I have 20 pdf documents opened at the same time.

Edit 2 Following @meuh suggestion I tried the following

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"

and in my .xmonad file:

[...]
-- find corresponding tex file
    , ((modm,               xK_p     ), spawn "get_tex_name.sh")
    

Now if I have a focused evince instance and run the stript via Windows-p, it doesn't seem to get the filename (I think because xprop doesn't seem to return the pid of the focused window but only after clicking on it).

So how to make it work?

1 Answer 1

1

There are many tools available to automate this action. Of course, the first consideration might be to view pdf files within emacs, which it is capable of doing. You then have ready access to the filename and manipulation of it by elisp.

Outside emacs, you can use, for example,

pgrep -xa evince

to find the process id and command line of evince, and so extract the filename it was launched with. Or if you selected a file interactively within evince, you can use

ls -l /proc/"$pid"/fd/

(where pid came from the earlier pgrep) to see what file descriptors are open, and choose the one ending with pdf, to get the name of the pdf file.

If you have several evinces running, you can use

xprop _NET_WM_PID

to interactively click on a given window, and get the process id of that program. Unfortunately, evince does not put the full filename into an X11 property.

To pass the filename to emacs, use emacsclient after doing (server-start) in emacs.

To set up a keybinding for the combined script, see xmonad.


Here's a possible bash script

#!/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"
4
  • Thanks. Yes, I know that emacs can view pdf's directly. I tried it in the past, but it felt a bit slow and continous scrolling doesn't work well enough (but that may change in the future). As you already mentioned xprop doesn't return the filename and the relevant case is that I have lot's of evince instances opened at the same time.
    – student
    Aug 30, 2022 at 20:07
  • My version of evince forks a separate process for each file opened, even from within evince. With xprop _NET_WM_PID, since no window id is provided, it prompts you to click on a window. When you click on a given evince window, you will get a unique process id, which you can transform into a unique filename by using the /proc/"$pid"/fd/ information.
    – meuh
    Aug 31, 2022 at 7:49
  • The problem is, that xprop only seems to return a pid if its running in the background and you click on a window afterwards. So I didn't see exactly how to implement it (see my second edit above).
    – student
    Sep 2, 2022 at 4:41
  • 1
    I added a possible script. If you have further problems you should probably start a new question so others may be able to answer.
    – meuh
    Sep 2, 2022 at 6:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .