Auto-update tmux status bar with active pane pwd

痞子三分冷 提交于 2019-11-30 14:22:07

Tmux pane PWD at the prompt

There are several ways that you can do this. I do it myself. The easiest and most customisable way is to set a global variable that tmux can access.

First add this to your .bashrc or .zshrc file, to set the PWD variable after every prompt:

# create a global per-pane variable that holds the pane's PWD
export PS1=$PS1'$( [ -n $TMUX ] && tmux setenv -g TMUX_PWD_$(tmux display -p "#D" | tr -d %) $PWD)'

Now, make a script that displays this variable such as ~/bin/display_tmux_pane_pwd.sh:

#!/bin/bash
tmux showenv -g TMUX_PWD_$(tmux display -p "#D" | tr -d %)  | sed 's/^.*=//'

All that is left is to add this to the satis-bar in .tmux.conf:

set -g status-left '#(~/bin/display_tmux_pane_pwd.sh)'

It may take awhile to update after switching panes, so you can change that with this command. By default it updates every 15 seconds, this will make it 5 seconds. Change it as you like.

set -g status-interval 5

Tmux-pane PWD in other programs

Sometimes it is useful to open up a pane or window and immediately execute a program instead of booting up another shell (e.g. tmux new-window vim). This way, when you close that program you also close the window. Unfortunately, the way I describe above requires a prompt in order to broadcast the status of PWD. However, in many programs, you can work around this fairly easily. Here's an example of what is in my .vimrc file so that vim updates the PWD status whenever it changes buffers.

if exists("$TMUX")
    " Get the environment variable
    let tmux_pane_name_cmd = 'tmux display -p \#D'
    let tmux_pane_name = substitute(system(g:tmux_pane_name_cmd), "\n", "", "")
    let tmux_env_var = "TMUX_PWD_" . substitute(g:tmux_pane_name, "%", "", "")
    unlet tmux_pane_name tmux_pane_name_cmd
    function! BroadcastTmuxCwd()
        let filename = substitute(expand("%:p:h"), $HOME, "~", "")
        let output = system("tmux setenv -g ".g:tmux_env_var." ".l:filename)
    endfunction
    autocmd BufEnter * call BroadcastTmuxCwd()
endif
gospes

In addition to the previous answer, I'd like to add you don't have to rely on the status-interval option. Waiting to see the change isn't really elegant. You can manually update the status bar on events with:

tmux refresh-client -S

I use this option after pane/window/session switching. In my tmux config you will find for instance to switch panes:

bind -r k select-pane -U\; refresh-client -S
bind -r j select-pane -D\; refresh-client -S
bind -r l select-pane -R\; refresh-client -S
bind -r h select-pane -L\; refresh-client -S

I have previously posted on this: manually refresh status bar

If you want the current window name to reflect the directory name, here is a modified version of the original answer that does not require calling a script from tmux and updates instantly:

export PS1=$PS1'$( [ -n $TMUX ] && tmux rename-window $(basename $PWD))'

Note that this means that you can't display the current process name any longer. It is of little value for me anyway.

This is another way to do this.

Working ENV:

OS

  • OSX 10.14.5

Terminal

Tmux

  • tmux 2.9a

Example status-right field

~/.tmux.config to call out to an external bash script in the example provided, the file is here: ~/.tmux_path.sh

~/.tmux.config

set -g status-interval 1
set -g status-right-length 150
set -g status-right "#(~/.tmux_path.sh #{pane_current_path}) %Y-%m-%d %H:%M:%S"

Example bash script that reads #{pane_current_path) arg. basename truncates the beginning path and just displays current. This is nice if using as a window id.

~/.tmux_path.sh

#!/bin/sh
printf '\033%s\007' $(basename $1) # show full path use $1 instead of $(basename $1)

Make script executable

chmod +x ~/.tmux_path.sh

Example window naming

  • Note: Use the same ~/.tmux_path.sh from above

~/.tmux.conf

set -g status-interval 1
set -g window-status-current-format "[#[fg=white] #(~/.tmux_path.sh #{pane_current_path})]"
set -g window-status-format "#[fg=black] #(~/.tmux_path.sh #{pane_current_path})"
    0

    I solved this by adding this to my .zshrc (or .bashrc):

    cd() { builtin cd $1 tmux refresh-client -S }

    Then binding tmux refresh-client -S to pane switching as others have done.

      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.

      标签
      易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
      该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!