0

How to make (N)Vim auto save buffer on Tmux select-pane? In my vimrc I tried:

" Auto save when buffer lose focus
autocmd FocusLost,BufLeave * silent! wa

" Save on buffer change
set autowrite 

But it does not work. In Termite (terminal emulator), in Tmux while cursor in vim pane, I press <C-|>l to select right pane (select-pane command). My cursor goes to the right pane but the vim buffer is not saved. It does autosave when I use NVim-qt or when I use Termite with Vim.

My .tmux.config:

setw -g mode-keys vi 

# Use other prefix.
unbind-key C-b
set -g prefix 'C-\'
bind-key 'C-\' send-prefix

bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
  • 1
    Last time I checked FocusGained and FocusLost only worked on GUI versions. Most of the terminal emulator don't send the right codes to be able to handle these events. I think that's why this plugin was created but IIRC I didn't get it to work on neovim. (Note that I didn't check that recently and my comment could be outdated and not true anymore) – statox Dec 17 '19 at 8:56
  • 1
    Similar question at vi.stackexchange.com/questions/18515/… – Artyom Dec 18 '19 at 11:13
3

I don't know if vim supports focus but if it does you will at least need to turn focus-events on in .tmux.conf:

set -g focus-events on
| improve this answer | |
3

I don't know whether it will work for you because I don't have termite, but you could try to add this line in your tmux.conf:

set -s focus-events on

And these lines in your vimrc:

if !has('nvim') && !has('gui_running')
    let &t_ti ..= "\e[?1004h"
    let &t_te ..= "\e[?1004l"
    exe "set <S-F18>=\e[O"
    exe "set <S-F19>=\e[I"

    nno <silent><expr> <S-F18> <sid>do('FocusLost')
    nno <silent><expr> <S-F19> <sid>do('FocusGained')
    ono <silent> <S-F18> <esc>:call <sid>do('FocusLost')<cr>
    ono <silent> <S-F19> <esc>:call <sid>do('FocusGained')<cr>
    vno <silent> <S-F18> <esc>:call <sid>do('FocusLost')<cr>gv
    vno <silent> <S-F19> <esc>:call <sid>do('FocusGained')<cr>gv
    ino <silent> <S-F18> <c-r>=<sid>do('FocusLost')<cr>
    ino <silent> <S-F19> <c-r>=<sid>do('FocusGained')<cr>
    cno <S-F18> <c-r>=<sid>do('FocusLost')<cr>
    cno <S-F19> <c-r>=<sid>do('FocusGained')<cr>
    exe 'tno <silent> <S-F18> '..&termwinkey..":call <sid>do('FocusLost')<cr>"
    exe 'tno <silent> <S-F19> '..&termwinkey..":call <sid>do('FocusGained')<cr>"

    fu s:do(event) abort
        if maparg('<s-f18>', 'n', 0, 1).expr
            nno <silent> <S-F18> :<c-u>call <sid>do('FocusLost')<cr>
            nno <silent> <S-F19> :<c-u>call <sid>do('FocusGained')<cr>
        else
            if exists('#'..a:event)
                exe 'do <nomodeline> '..a:event
            endif
        endif
        return ''
    endfu
endif

It works in xterm (with patch level 322). However, this is a hack; it can create an issue in Tmux, where sometimes you can't copy some multi-line text in the output of a Vim Ex command via Tmux copy-mode.

It can also create a similar issue in Vim, where a multi-line Ex command output is cleared after focusing a different program window.

IIRC, it can also cause the screen not to be always correctly redrawn after you push a commit with vim-fugitive.


There is an item at :h todo which mentions a Vim patch making FocusGained and FocusLost work in modern terminals:

Patch to make FocusGained and FocusLost work in modern terminals. (Hayaki Saito, 2013 Apr 24) Update 2016 Aug 12. Also see issue #609.

The latest version of the patch is about 3 years old, so it probably needs to be updated.

There is also a github issue which asks for these events to work in Vim.

Anyway, if an updated version of this patch was merged, you would not need the previous hack anymore, and you probably would not face the previously mentioned issues.

However, as Nicholas Marriott explained, you'll still need the line set -s focus-events on in your tmux.conf.


Note that in Nvim, FocusGained and FocusLost should work without the hack (hence why the guard contains !has('nvim')).

| improve this answer | |

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.