35

I'm new to tmux and am trying to figure out how to edit the configuration so that windows with vim open show up in the taskbar not as #:vim but as whatever the name of the file open in vim is
(ie "#:filename.php"). Seems like it should be a common thing, but my search - foo is failing.

kelly
  • 415
  • 2
  • 9
  • 24
attack attack
  • 353
  • 1
  • 3
  • 6
  • 3
    I use split a lot in vim. if I open 10 files in buffers and split 4 files into 4 windows, you tell me, what you want to show in tmux window label? – Kent Feb 27 '13 at 22:19
  • 1
    @Kent Suppose there's just a single file open in a single window. Can this be done? – Matt Parker Feb 27 '13 at 22:55
  • 1
    Kent: you could define appropriate autocommands in Vim to call `tmux rename-window` with the name of the file in the active buffer. – chepner Feb 27 '13 at 22:57

8 Answers8

43

Here's a partial answer. It can be improved, but I don't have time to work it out right now.

Put the following in your .vimrc:

autocmd BufReadPost,FileReadPost,BufNewFile * call system("tmux rename-window " . expand("%"))

There are other events (see :help autocmd-events in Vim) that may be used to handle as well. One thing I haven't figured out is how to change the window name if you have an instance of vim open in each of two panes, and you switch from one pane to the other. vim is unaware of the activity in tmux, so no vim events are triggered.

arved
  • 4,401
  • 4
  • 30
  • 53
chepner
  • 497,756
  • 71
  • 530
  • 681
  • 15
    I had to tweak this to use expand() to get the percentage sign to expand to the window name, otherwise I was just getting "%" as my window name. This was with vim 7.3. I.e.: autocmd BufReadPost,FileReadPost,BufNewFile * call system("tmux rename-window " . expand("%")) – Von Apr 19 '13 at 18:51
  • 7
    I've found when using multiple panes or windows, or fugitive I needed to add BufEnter to the list of events to have the title keep up when moving around between buffers. – Von May 02 '13 at 13:06
  • 9
    expand("%:t") would put the file name while expand("%") displays the full path. – Nobu Aug 28 '13 at 18:24
  • Possibly missing: you need to set `t_ts`. This works for tmux/screen: `set t_ts=^[k`. (Use ctrl-v, ESC to enter the `^[` character as an actual escape, as required.) – Asherah Mar 05 '14 at 02:34
  • In order to get this to work with iTerm2 I needed to also `set-titles` in the tmux.conf as described here - http://superuser.com/questions/702156/rename-iterm2-tab-from-within-tmux – studgeek Apr 09 '16 at 05:07
  • 4
    This seems to leave the window renamed after you leave vim. To fix that I added `autocmd VimLeave * call system("tmux rename-window bash")` as described in @Phluks answer. – studgeek Apr 09 '16 at 05:08
  • I have just made an answer below, this avoids the external commands. – dza Feb 07 '23 at 02:28
18

It is possible! I wanted to share this answer because I've been looking for it for quite some time. Finally got the time to implement it myself. Put the following in your .vimrc:

autocmd BufEnter * let &titlestring = ' ' . expand("%:t")
set title

It will set the terminal title to only the document title currently in focus (%t stands for the document title without the path). Thanks to the event BufEnter, the terminal title changes each time you switch focus to another document. Also when leaving Vim, it is changed back to the original state. Put (or replace) the following in your .tmux.conf:

set-window-option -g window-status-current-format "[#I #W#T]"
set-window-option -g window-status-format "[#I #W#T]"

It is not necessary to copy it exactly, but it looks like so:

[1 vim .tmux.conf][2 bash]...

The I stands for the window number. The W stands for the current application being run and the T stand for the terminal title. The later we use to show the current file open in vim. The terminal title is always set (my bash terminal always shows the hostname which i don't need to see in my status bar descriptions), so to only show it when vim runs add the following to your .bashrc:

PROMPT_COMMAND='echo -ne "\033]0;\007"'

This is true for bash, the shell I use. PROMPT_COMMAND is evaluated just before your prompt is shown in the terminal. The echo command sets the terminal title to nothing. This action thus happens each time you get your prompt back from applications who might have changed the title. Other shells might need to be configured differently...

I wouldn't use tmux rename-window as it sets the title for as long as the windows exists. You would need to call it for each application launch. The presented approach keeps things dynamic, as it works with multiple panes in a window and multiple split screens/files open within vim.

gospes
  • 3,819
  • 1
  • 28
  • 31
  • I tried this without any luck. Any debugging tips? I did restart tmux. – Rose Perrone Jun 26 '13 at 15:44
  • This isn't enough information to go on but so best guesses are you are not using bash as default terminal. TMUX can be force to use bash by putting "set-option -g default-shell /bin/bash" in your ".tmux.conf". Perhaps you are not seeing the status bar which can be fixed by adding "set-option -g status on". Any luck? – gospes Jul 01 '13 at 08:19
  • 1
    `autocmd BufEnter * let &titlestring = ' ' . expand("%:t")` doesn't seem to work for me inside tmux. As @Phluks suggested, I used the `tmux rename-window` approach when inside tmux. – studgeek Apr 09 '16 at 05:04
  • I just figured out you what you refer to as the `terminal title` is what I believe tmux calls the `pane title` and you getting at the same answer I just posted below. What you are missing, at least for this to work for me, is setting `t_ts` and `t_fs` – Von May 10 '16 at 01:11
10

Thanks for great input guys it saves me a lot of typing :-)

I combined the two previous answers into one, that I like.

autocmd BufEnter * call system("tmux rename-window " . expand("%:t"))
autocmd VimLeave * call system("tmux rename-window bash")
autocmd BufEnter * let &titlestring = ' ' . expand("%:t")                                                                 
set title

The first and sedond line are for tmux and the third and 4th are for normal terminal use. You don't have to restart tmux since it is vim that updates tmux explicitly.

Phluks
  • 906
  • 1
  • 9
  • 14
9

And to restore automatic window title on Vim exit:

autocmd VimLeave * call system("tmux setw automatic-rename")

I would also suggest to check if we are running under tmux:

if exists('$TMUX')
    autocmd BufEnter * call system("tmux rename-window '" . expand("%:t") . "'")
    autocmd VimLeave * call system("tmux setw automatic-rename")
endif
sc0ty
  • 193
  • 1
  • 7
2

Great answers here, but I still couldn't get it to work the way I wanted it, which is: 1) Change the TMUX window name on opening vim 2) On quit. return it to the previous name when finished I achieved it with the following 3 vimrc lines:

autocmd BufReadPost,FileReadPost,BufNewFile * call system("tmux rename-window " . expand("%:t"))
let tmuxtitle = system("tmux display-message -p '#W'")
autocmd VimLeave * call system("tmux rename-window " . shellescape(tmuxtitle))
Arthur
  • 61
  • 5
2

As an alternative to other answers which set the tmux window name, you can have vim set the tmux pane title instead. This lets you keep a static window name that you define with tmux new-window -n <window-name> while having vim change the pane title. You can use #T in set-titles-string to display the pane title, e.g. set-option -g set-titles-string "#W: #T" will display tmux window name and pane title.

Example vim configuration to change pane title:

" Teach vim the tmux escape sequences for changing pane title
" Note the "^[" should be a literal escape code (use `^v<esc>` to enter it)
set t_ts=^[]2;
set t_fs=^[\\

" Turn on setting the title.
set title

" The following causes vim to refresh the title each time we change buffers.
" Otherwise it will only set the title once at startup.
augroup RefreshTitle
  autocmd!
  " The concatenation of the colon is a hack to prevent vim from
  " interpreting the string as a modeline.
  autocmd BufEnter * let &titlestring = "vim" . ":" . expand("%:t")
augroup END

Kudos to vim.wikia.com for the t_ts and t_fs guidance and phluks for the autocommand.

Community
  • 1
  • 1
Von
  • 4,365
  • 2
  • 29
  • 29
  • FWIW, for me just "set title" and "set titlestring=%t" kept the pane title up-to-date as I switch buffers, and I didn't need the augroup/BufEnter command. – Stephen Haberman Jan 02 '17 at 18:56
2

Here's my method of doing this while also renaming the window when navigating back and forth between panes and limiting the number of characters displayed.

vim_demo


~/.tmux.conf

I prefer title names without index numbers or other symbols.

basepath/   -> at the prompt
filename    -> inside Vim

To keep the index number, change the window-status-format and window-status-current-format lines to "#I:#W".

# window name formatting
set-window-option -g window-status-format "#W"
set-window-option -g window-status-current-format "#W"

# pane title formatting
set -g pane-border-format ' #T '

# rename window to pane title on focus
set -g focus-events on
set-hook -g pane-focus-in 'rename-window "#T"'

Source tmux.conf
tmux source-file ~/.tmux.conf

~/.bashrc

I ending up using bash as it allows for immediate window renaming when changing directories and ended up being easier for my particular needs than vimscript. It changes the functionality of the cd and vim commands to include my renaming functions. I also added in functionality for when using top and nmtui to rename to the commands themselves.

# max number of characters in title
CHAR_LIMIT=20
MY_VIM="/usr/bin/vim.gtk3"

# if tmux running...
tmux ls > /dev/null 2>&1
TMUX_STATUS=$?
if [ $TMUX_STATUS -eq 0 ]; then

    basedirRename () {

        # "basepath/"
        getval=$(pwd)
        BASEPATH_FULL="${getval##*/}"
        BASEPATH="${BASEPATH_FULL:0:$CHAR_LIMIT}/"

        tmux rename-window " $BASEPATH "
        tmux select-pane -T " $BASEPATH "
    }
    
    fileRename () {

        # "filename"
        FILENAME_FULL="$@"
        FILENAME="${FILENAME_FULL:0:$CHAR_LIMIT}"

        tmux rename-window " $FILENAME "
        tmux select-pane -T " $FILENAME "
    }

    commandRename() {
        tmux rename-window " $1 "
        tmux select-pane -T " $1 "
    }

    cd () {

        builtin cd "$@"
        CD_STATUS=$?
        basedirRename
        return "$CD_STATUS"
    }

    vim () {

        fileRename $@
        $MY_VIM $@
        VIM_STATUS="$?"
        basedirRename
        return "$VIM_STATUS"
    }

    top () { commandRename 'top'; /usr/bin/top; STATUS=$@; basedirRename; return $STATUS; }
    nmtui () { commandRename 'nmtui'; /usr/bin/nmtui; STATUS=$@; basedirRename; return $STATUS; }

    basedirRename
fi



Source .bashrc
. .bashrc

Jeff_V
  • 41
  • 1
  • 5
  • Yours is the most elaborated answer to date. But needs some refinement. Works with vim and in the terminal showing pwd , but if you use a program say top , it will stop renaming the window as such – freddie_ventura Jun 06 '23 at 15:57
  • Also if it would ignore to rename the manualy renamed windows , that would be great too – freddie_ventura Jun 06 '23 at 17:04
  • Also It doesnt work if a whole session is called with a script – freddie_ventura Jun 06 '23 at 17:16
  • 1
    @freddie_ventura Just when I think I'm done with this thing lol. But the command renaming is a solid suggestion. I added it for top and nmtui in .bashrc to show how. I don't manually rename windows or use sessions. Good luck with that. – Jeff_V Jun 06 '23 at 18:33
1

.tmux.conf

set-option -g set-titles on
set-option -g set-titles-string '#W:#T' # window title,pane title
set -g allow-rename on

This is how I set the titlestring in vim: https://vi.stackexchange.com/a/40069/26406

No need to use external commands from within vim, this is the way.

dza
  • 1,478
  • 2
  • 13
  • 24