attack attack
attack attack

Reputation: 353

tmux tabs with name of file open in vim

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.

Upvotes: 35

Views: 12428

Answers (8)

Jeff_V
Jeff_V

Reputation: 61

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

Upvotes: 2

dza
dza

Reputation: 1504

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

Upvotes: 1

chepner
chepner

Reputation: 532093

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.

Upvotes: 44

sc0ty
sc0ty

Reputation: 213

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

Upvotes: 9

Von
Von

Reputation: 4525

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.

Upvotes: 2

Arthur
Arthur

Reputation: 61

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))

Upvotes: 2

Phluks
Phluks

Reputation: 916

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.

Upvotes: 10

gospes
gospes

Reputation: 3947

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.

Upvotes: 18

Related Questions