3

As of tmux 2.6, tmux now allows per-pane titles. They can be enabled via tmux set -g pane-border-status top. This is very convenient when running 10+ panes per window. I also set my title format as follows, to allow me to rename them:

set -g pane-border-format "#{pane_index} #{pane_title}"
# rename prompt
bind . command-prompt -p "(rename-pane)" -I "#T" "select-pane -T '%%'"

The only thing I don't like is the fallback default, which defaults to hostname of the machine. I would prefer the following instead:

  • if pane_title is set by the user, use that (#{pane_title})
  • otherwise, use current working directory (#{pane_current_path})

Either one by itself is straight-forward:

  • tmux set -g pane-border-format "#{pane_index} #{pane_title}"
  • tmux set -g pane-border-format "#{pane_index} #{pane_current_path}"

The formatting section of tmux (https://github.com/tmux/tmux/wiki/Formats) shows that I can use a ternary conditional check to achieve the kind of fallback I want, but I'm having trouble getting it working in all cases due to the fact that pane_index, when unset, seems to default to (my guess) whatever hostname command returned at the time the pane was spawned. Here is what I currently have:

tmux set -g pane-border-format "#{pane_index} #{?#{!=:#{pane_title},$(hostname)},#{pane_title},#{pane_current_path}}"

This works for panes that have been explicitly renamed by the user, and also for panes that were spawned with the same hostname. Unfortunately, the hostname on my work machine changes with IP, so the above command seems too fragile. To make things worse, for some reason it only works when ran directly from a pane rather than when put into tmux config (without the tmux prefix, of course). Is there a better way to determine if pane_title is unset?

2

You could try using hooks to set the pane title of new panes to something more recognizable, something like:

set-hook -g after-split-window 'selectp -T ""'
set-hook -g after-new-window 'selectp -T ""'
set-hook -g after-new-session 'selectp -T ""'

Then look for an empty title rather than the hostname:

#{?pane_title,#{pane_title},#{pane_current_comamnd}}
| improve this answer | |
1

I'm not sure if I can answer all of your questions, but I can take a stab at a few issues.

In my config I have this monstrocity:

setw -g pane-border-format ' #{=/-20/…:pane_title} [#{=/-20/…:pane_current_command}] #(pgrep -P "#{pane_pid}" | tr "\n" " ")#{pane_current_path} #{?alternate_on,<Alt Mode> ,}'

(Some of this may rely on tmux ~3.1 features)

use of setw -g instead of set -g may make it work for you from config.

As you can see my approach is to just jam everything I might want to know about into it, because you'd be wasting the rest of the space in that border line anyway, if you dont use it or try to be stingy with the space. Rarely do terminals get sized smaller than say 60 cols, so I see zero value in keeping the border content line compact. Using a low contrast color for the border is key here, to preserve a more or less clean look. So that addresses the awkwardness of trying to control what to display in that field: Consider not trying to control what to display and display both.

The other thing about pane title is that it is "supposed" to be set by the shell and/or the program the shell is running. This caused me a great deal of headache back in October of last year, though I do know that I got the problem solved. As of right now neither my brain nor my git logs can provide enough information to say for sure what the right thing you need to do is to control how the pane_title is set, but suffice it to say it is one of those complex things where you'll need to touch your bash/zsh configuration to do it, and that that is the thing that is probably responsible for assigning it to your hostname, rather than something more useful such as cwd or active command line.

I believe I had to add the :XT string to my terminal-overrides to assist in this working properly. See https://unix.stackexchange.com/a/75382/12497

It's been a long road for me to get this working right, and it was important too, because pane_title is so far the only reliable straightforward way to check what program is actually probably running inside a pane. Since I got that working, my context-sensitive tmux key binds (which predicate on the value of pane_title) are working flawlessly: When zsh is active, pane_title is set by zsh to the last command that was run, when vim starts it overrides the pane title with a specific string I set in my vimrc, etc. This works well to control my context sensitive key bindings. One of the issues that was massive before was if a script "myscript" runs Vim then pane_title becomes "myscript", making it impossible for my key binding system to know I'm running Vim in the pane. Now that Vim is empowered to update the terminal title, and correctly sets it in the tmux pane, the logic to check if a pane runs vim is greatly simplified.

Another way to go about detecting what's running inside a pane is to query the operating system to see about what the processes are, since we do have access to PIDs. But I've been avoiding going too nuts with pipes for that sort of thing so far, in favor of "standard" capabilities. I'm sure if pane_title ended up defeating me I'd've written a C++ program that prints what i'm running in the relevant pane. Good luck.

| improve this answer | |
  • 1
    If you are going to query processes running in the pane, it is better to use #{pane_tty} rather than the PID - all the processes should have the same controlling terminal, even if they may not necessarily be related to the original PID. I think you can do this using ps on most platforms. But if you only want to pick the "best" process, you may as well let tmux do it and use #{pane_current_command}. – Nicholas Marriott Jan 29 at 8:22

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.