3

I use tmux at work as my IDE. I also run vim in a variety of tmux panes and will fairly often background the process (or alternatively I just close the window - I have vim configured not to remove open buffers when the window is closed). Now I've a problem, because a file that I want to edit is open in one of my other vim sessions but I don't know which one.

Is it possible to find out which one, without manually going through all my windows and panes? In my particular case, I know that I didn't edit it with vim ~/myfile.txt because ps aux | grep myfile.txt doesn't return anything.

8

It doesn't tell me everything, but I used fuser ~/.myfile.txt.swp which gave me the PID of the vim session. Running ps aux | grep <PID> I was able to find out which vim session I was using, which gave me a hint as to which window I had it open in.

Thanks to Giles's inspiration and a bit of persistence and luck, I came up with the following command:

⚘ (FNAME="/tmp/.fnord.txt.swp"; tmux switch -t $(tmux list-panes -a -F '#{session_name}:#{window_index}.#{pane_index} #{pane_tty}' | grep $(ps -o tty= -p $(lsof -t $FNAME))$ | awk '{ print $1 }'))

To explain what this does:

(FNAME="/tmp/.fnord.txt.swp";

This creates a subshell and sets FNAME as an environment variable. It's not, strictly speaking, necessary - you could just replace $FNAME with the filename yourself, but it does make editing things easier. Now, working from the inside out:

lsof -t $FNAME

This produces only the PID of the process that has open the file.

ps -o tty= -p $(...)

This produces the pts of the PID that we found using lsof.

tmux list-panes -a -F '#{session_name}:#{window_index}.#{pane_index} #{pane_tty}'

This produces a pane list of entries like session:0.1 /dev/pts/1. The first part is the format that tmux likes for targets, and the second part is the pts

| grep $(...)$

This filters our pane list - the trailing $ is so it will only match the one we care about. I discovered that quite by accident as I had pts/2 and pts/22, so there were two matches, whoops!

| awk '{ print $1 }'

This produces the session:0.1 part of the pane output, which is suitable for passing to tmux switch -t.

This should work across sessions as well as panes, bringing to focus the pane that contains your swap file.

  • 1
    Don't grep for the PID! ps -p "$pid" lists that specific PID. And while you're at it, the useful information there is probably the terminal name: ps -o tty= -p "$pid". That identifies the tmux window where this instance of vim is running. I don't know how to do the next step of focusing a window based on the terminal name, maybe something with switch-client. – Gilles Sep 14 '16 at 1:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.