5

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.

2 Answers 2

9

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
  • 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. Commented Sep 14, 2016 at 1:55
0

the outline answer to your question is:

for all the tmux sessions:
  for all the windows in the session:
      for all the panes in windows:
         for all sub process pids (recursively):
            find the open files

all sessions: tmux list-sessions -F '#{session_id}:#{session_name}

all windows: tmux list-windows -F '#{window_id}XX#{window_index}XX#{window_name}' -t "$session_id"

all panes: tmux list-panes -F '#{pane_id}:#{pane_index}:#{pane_pid}' -t ""$session_id":"$window_index""

all sub processe pids: ps -o pid --no-headers --ppid $pid

open files: lsof -p $pid

An implementation of the above which displays a tree of:

sessions
   windows
      panes
         process
            open files

to show which process has a file open (vim in my case too).

enter image description here

can be found at https://github.com/nkh/tmux-ls

it's been on github for 5 year but I encourage you to clone it in case it is removed (or github crashes)

3
  • Whilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference. Commented Oct 6, 2021 at 8:04
  • @TobySpeight Normally I would agree, but the script posted by the author in GitHub is rather lengthy and would not really fit the format of an SE answer, so in this case I think referencing the external resource is reasonable.
    – AdminBee
    Commented Oct 6, 2021 at 9:57
  • A good answer would describe enough that it remains an answer even when the link itself isn't accessible. I think at least the principles used should be present for this not to be "your answer is in another castle." Commented Oct 6, 2021 at 10:43

You must log in to answer this question.

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