71

I would like to have tmux to automatically rename the window with the current working directory (cwd). As it is by default, it names the tab/window as the name of the current process, such as zsh or vim.

When I open a new window in tmux, the name is reattach-to-use-namespace and then it immediately switches to zsh.

tmux tabs

I'm on OS X 10.10.2, I use zshell, and I have tmux 1.9a.

To be clear, I don't want the entire path in the name of the window, just the current directory, so for example, I want projectName, not /Users/username/Development/projectName.

If you want to see my current tmux.conf, here it is.

aharris88
  • 3,560
  • 3
  • 27
  • 45

11 Answers11

82

With tmux 2.3+, the b: format modifier shows the "basename" (or "tail") of a path.

set-option -g status-interval 5
set-option -g automatic-rename on
set-option -g automatic-rename-format '#{b:pane_current_path}'

The FORMATS section of man tmux describes other modifiers, such as #{d:} and even #{s/foo/bar/:}.


With tmux 2.2 or older, the basename shell command can be used instead.

set-option -g status-interval 5
set-option -g automatic-rename on
set-option -g automatic-rename-format '#(basename "#{pane_current_path}")'
Justin M. Keyes
  • 6,679
  • 3
  • 33
  • 60
  • 1
    Thanks for showing both ways, and since the 2.3 version will also work on newer (slightly slower since it has to shell out) I'll put that in my configs until I can get all the machines I work on to 2.3 or newer. – dragon788 May 16 '18 at 16:31
  • 4
    is there a way to get `~` for `~` rather than the full username? – Toothrot Feb 01 '20 at 20:01
  • 3
    @Toothrot sure! `#{b;s/your_username/~/:pane_current_path}` is the way to go – Wiesław Herr Apr 21 '21 at 19:19
35

Expanding on what Josef wrote, you can put the basename of the directory in the status using a shell snippet:

# be sure to see note* below
set -g window-status-format '#I:#(pwd="#{pane_current_path}"; echo ${pwd####*/})#F'
set -g window-status-current-format '#I:#(pwd="#{pane_current_path}"; echo ${pwd####*/})#F'

# status bar updates every 15s by default**, change to 1s here 
# (this step is optional - a lower latency might have negative battery/cpu usage impacts)
set -g status-interval 1

*Note that what would be ${pwd##*/} is escaped to ${pwd####*/} since # has special meaning in the format string.

**See here for an example default tmux config.

yiwei
  • 4,022
  • 9
  • 36
  • 54
CEL
  • 848
  • 7
  • 10
  • 4
    This, actually, does not set window name, but only status. Use `tmux list-windows` to check. – paulodiovani Jun 16 '16 at 16:27
  • 1
    This works brilliantly to set the window status (which is what shows up in the bottom of the screen for each window) as @paulodiovani pointed out. It's worth mentioning the `status-interval` is so that it updates faster when changing directories, but you could leave it out and the lag isn't too bad. – Leigh McCulloch Aug 01 '16 at 05:44
  • What's the meaning of `#I`, `#F`? Is there any doc for the syntax? – nn0p Jun 21 '18 at 02:44
  • 1
    @nn0p: from the tmux map page: `#I Current window index` and `#F Current window flag` (`*` if selected) – Vincent de Lagabbe Dec 18 '18 at 09:19
  • This didn't work for me at first ("Invalid environment variable") because I used double quotes. Changing to single quotes fixed it. – erb May 19 '20 at 09:09
23

Show the top N components

enter image description here

Showing just the basename generates too much ambiguity, but full paths are too much clutter, so I settled for:

the/last/path

instead of:

/a/very/long/the/last/path

or just:

path

.tmux.conf

set-window-option -g window-status-current-format '#[fg=white,bold]** #{window_index} #[fg=green]#{pane_current_command} #[fg=blue]#(echo "#{pane_current_path}" | rev | cut -d'/' -f-3 | rev) #[fg=white]**|'
set-window-option -g window-status-format '#[fg=white,bold]#{window_index} #[fg=green]#{pane_current_command} #[fg=blue]#(echo "#{pane_current_path}" | rev | cut -d'/' -f-3 | rev) #[fg=white]|'

Trick taken from: Remove part of path on Unix

If that still does not solve ambiguity, I go for:

bind-key -r w choose-window -F '#{window_index} | #{pane_current_command} | #{host} | #{pane_current_path}'

Tested on Tmux 2.1, Ubuntu 16.04.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
  • Partial path doesn't work for me. When the command #(echo "#{pane_current_path}" | rev gets executed it gives output as }htap_tnerruc_enap{# . So basically it gives input to echo after reversing. – hrishi Nov 24 '16 at 08:42
  • @HrishikeshGoyal thanks for report. What is your tmux version? – Ciro Santilli OurBigBook.com Nov 24 '16 at 11:31
  • I am using tmux 2.0 – hrishi Nov 24 '16 at 14:35
  • 1
    One up for @CiroSantilli新疆改造中心六四事件法轮功 If that still does not solve ambiguity, I go for: bind-key -r w choose-window -F '#{window_index} | #{pane_current_command} | #{host} | #{pane_current_path}' – Rho Phi Feb 15 '19 at 09:33
13

To get the best of both worlds - window name is path when you're at a shell prompt, but name of executable when you're running something, try this:

set-option -g status-interval 1
set-option -g automatic-rename on
set-option -g automatic-rename-format "#{?#{==:#{pane_current_command},bash},#{b:pane_current_path},#{pane_current_command}}"

Replace "bash" with whatever shell you're using.

Greg Bell
  • 2,032
  • 1
  • 18
  • 18
3

Adding this config to your ~/.tmux.conf file should work:

set-option -g window-status-current-format '#I:#{pane_current_path}#F'
set-option -g window-status-format '#I:#{pane_current_path}#F'
set-option -g status-interval 1

It depends however on your Tmux version. I wasn't able to make it work on 1.9a3 (in Cygwin) - but with Tmux 1.8 on Ubuntu (in Vagrant) it worked fine.

Josef Cech
  • 2,115
  • 16
  • 17
  • Yeah, it does nothing for me. – aharris88 Feb 07 '15 at 16:11
  • 2
    this works great for me (OSX/tmux 1.9a), but is there a simple way to have it just be the basename? – pho79 Feb 25 '15 at 19:45
  • Unfortunately I'm not aware of it (commands from format string are in another environment) - you can try solution provided by JuniorCompressor (even if it's kind of hacky imho :]). – Josef Cech Mar 05 '15 at 19:33
3

I use the following in ~/.tmux.conf to achieve this (working on OSX, zsh, tmux-2.3):

set -g automatic-rename-format '#{pane_current_path}'
set -g status-interval 5

You can set status-interval to 1 to make it respond faster to changing directories.

According to the changelog (https://raw.githubusercontent.com/tmux/tmux/master/CHANGES) this should work in tmux 1.9 and up.

Using ssh into a CentOS machine with tmux 2.3 the window name doesn't change until I press return in the new panel, not sure why that is happening.

Harry Mallon
  • 825
  • 1
  • 8
  • 14
1

Do something like this in a tmux session for zsh shell:

setopt PROMPT_SUBST
export PS1=$'\ek$(basename $(pwd))\e\\> '

If someone uses bash shell:

export PS1="\033k\$(basename \$(pwd))\033\\> "

You can add these commands in the shell initialization file on the condition the $TERM env variable is set to the value "screen"

JuniorCompressor
  • 19,631
  • 4
  • 30
  • 57
  • I think you might have misunderstood my question. It looks like the command you gave here sets the prompt in the shell. I don't care about that. I want the windows in tmux named the current directory. I added an image to the question. – aharris88 Feb 07 '15 at 01:07
  • It doesn't only sets the prompt but also updates the title of the working window by running pwd command. I've tested in a debian and osx. Each time tmux shows the current working directory. – JuniorCompressor Feb 07 '15 at 09:08
  • I doesn't change the tmux window name for me. And it changes the prompt to `\W $\033k/Users/adamharris\033\ `. I'm on osx and my shell is zsh instead of bash. – aharris88 Feb 07 '15 at 16:05
  • In case of zsh try in a tmux shell: a) setopt PROMPT_SUBST b) export PS1=$'\ek$(pwd)\e\\> ' – JuniorCompressor Feb 08 '15 at 10:16
  • That works. The only problem is that I'm using powerline for my prompt, and it turns my zsh into a normal prompt. – aharris88 Feb 09 '15 at 18:20
  • @aharris88 did you manage to find any clean solution to this that works well with powerline? – Anchor May 07 '15 at 02:40
  • @Anchor I didn't. Also, I stopped using powerline because it's really hard to install on a new machine. – aharris88 May 07 '15 at 16:16
1

I am using zsh hook for that

Add following in ~/.zshrc

precmd () {
  if [ -n "$TMUX" ]; then
    tmux set-window-option -q window-status-format "#[fg=cyan bg=cyan] | #[fg=white, bg=cyan] #I | ${PWD##/*/} #[fg=cyan, bg=cyan] | "
    tmux set-window-option -q window-status-current-format "#[fg=cyan, bg=cyan] | #[fg=white, bg=cyan] #I | ${PWD##/*/} #[fg=cyan, bg=cyan] | "
  fi
}
logcat
  • 3,435
  • 1
  • 29
  • 44
0

This doesn't strictly answer your question--it doesn't automatically rename an existing tmux session to the current working directory.

Rather, when creating a new session, it names that session after the current working directory.

Here's what I did:

to

~/.aliases

add

alias tm='tmux new -s `basename $PWD`'

Open a new terminal window and type:

tm

This now creates a new tmux session which is named after the current working directory.

Note: This relies on basename which does not exist in Windows.

FreePender
  • 4,770
  • 2
  • 18
  • 15
  • 1
    Yeah, that's a bit different because I was asking about renaming the window status, not the session. But that's fine, I already got an answer that works. – aharris88 Jan 04 '17 at 21:02
0

I am sure that you want use this:

set -g status-left '#{pane_current_path} '

enter image description here

  • That doesn't look quite right. I want it to only show the current directory, not the entire path. The accepted answer worked for me. – aharris88 Sep 12 '18 at 18:33
0

To change what you see in the window list you can specify a format when you define the key-binding for the chose-window function like this:

bind-key '"'  choose-window  -F "#{session_name} | #{window_name} - #{b:pane_current_path} (#{pane_current_command})"
Rho Phi
  • 1,182
  • 1
  • 12
  • 21