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. 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. 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
    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." 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 .