├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── autoload └── tmux_focus_events.vim ├── plugin └── tmux_focus_events.vim └── vim_e813.png /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ### master 4 | 5 | ### v1.0.0, 2015-03-21 6 | - first working version 7 | - do not run outside tmux or in gui vim 8 | - copy and adapt FocusGained, FocusLost event triggering from 9 | https://github.com/sjl/vitality.vim 10 | - rename plugin to 'vim-tmux-focus-events' 11 | - add README 12 | - add the list of terminals where the plugin was tested and works 13 | - don't help `autoread` if it is not set 14 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (C) Bruno Sutic 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the "Software"), 5 | to deal in the Software without restriction, including without limitation 6 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | and/or sell copies of the Software, and to permit persons to whom the 8 | Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included 11 | in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 15 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 16 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 18 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 19 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tmux-focus-events.vim 2 | 3 | **Update:** this plugin is now obsolete and no longer needed as both neovim and 4 | vim (since version `8.2.2345`) have native support for this functionality. 5 | 6 | `FocusGained` and `FocusLost` autocommand events are not working 7 | in terminal vim. This plugin restores them when using vim inside Tmux. 8 | 9 | Here's where that matters: 10 | 11 | - [vim-fugitive](https://github.com/tpope/vim-fugitive) plugin uses 12 | `FocusGained` for refreshing git branch in status line 13 | - [vim-gitgutter](https://github.com/airblade/vim-gitgutter) uses `FocusGained` 14 | for refreshing ... (wait for it) git gutter 15 | - [vim-tmux-clipboard](https://github.com/roxma/vim-tmux-clipboard) uses 16 | `FocusGained` and `FocusLost` for refreshing clipboard. 17 | - (get in touch if you know other popular plugins that get improved) 18 | 19 | Also, `vim-tmux-focus-events` makes the 20 | [autoread](http://vimdoc.sourceforge.net/htmldoc/options.html#'autoread') 21 | option work properly for terminal vim. So far, this was only working in a GUI 22 | version. 23 | 24 | The `autoread` feature comes handy when files are changed outside vim, for 25 | example when resolving merge conflicts. When you come back to vim and try saving 26 | a changed file you'll likely be interrupted with 27 | [E813](http://vimdoc.sourceforge.net/htmldoc/editing.html#E813): 28 | 29 | ![vim E813](/vim_e813.png) 30 | 31 | Improved `autoread` prevents this by automatically reading a file from disk 32 | if it was changed. Works only if `autoread` option is set (enable it with 33 | `set autoread` in `.vimrc`). 34 | 35 | ### Installation & Configuration 36 | 37 | #### Vim plugin installation 38 | 39 | * Vundle
40 | `Plugin 'tmux-plugins/vim-tmux-focus-events'` 41 | 42 | * vim-plug
43 | `Plug 'tmux-plugins/vim-tmux-focus-events'` 44 | 45 | * Pathogen
46 | `git clone git://github.com/tmux-plugins/vim-tmux-focus-events.git ~/.vim/bundle/vim-tmux-focus-events` 47 | 48 | #### Tmux configuration 49 | 50 | In order for Tmux to do its magic `focus-events` option has to be set to `on`. 51 | 52 | Enable that by installing 53 | [tmux-sensible](https://github.com/tmux-plugins/tmux-sensible) plugin, or 54 | by setting this line in `tmux.conf`: 55 | 56 | set -g focus-events on 57 | 58 | ### Testing 59 | 60 | Tested and working on: 61 | 62 | - OS X 63 | - Terminal.app 64 | - iTerm2 65 | 66 | - Linux 67 | - GNOME Terminal 68 | - Terminator 69 | - XTerm 70 | - Konsole 71 | - st 72 | 73 | ### Usage 74 | 75 | Once installed, the plugin should "just work". 76 | 77 | It will have no effect when running GUI vim or inside plain terminal 78 | (without Tmux). 79 | 80 | ### Other goodies 81 | 82 | - [vim-tmux](https://github.com/tmux-plugins/vim-tmux) - vim plugin for 83 | `tmux.conf` 84 | - [tmux-resurrect](https://github.com/tmux-plugins/tmux-resurrect) - restore 85 | tmux environment after system restart 86 | 87 | ### Credits 88 | 89 | Big chunk of code was taken and adapted from 90 | [vitality.vim](https://github.com/sjl/vitality.vim). 91 | 92 | ### Other 93 | 94 | In April 2013 95 | [a patch was submitted](https://groups.google.com/forum/#!topic/vim_dev/ASn8QqQqVe0) 96 | to vim_dev mailing list that enables this functionality natively in vim. 97 | Once merged, the functionality from the patch will make this plugin obsolete. I 98 | hope that day comes soon. 99 | 100 | ### Licence 101 | 102 | [MIT](LICENSE.md) 103 | -------------------------------------------------------------------------------- /autoload/tmux_focus_events.vim: -------------------------------------------------------------------------------- 1 | if exists('g:autoloaded_tmux_focus_events') && g:autoloaded_tmux_focus_events 2 | finish 3 | endif 4 | let g:autoloaded_tmux_focus_events = 1 5 | 6 | let s:has_getcmdwintype = v:version > 704 || v:version == 704 && has("392") 7 | 8 | function! s:cursor_in_cmd_line() 9 | let in_cmd_line = !empty(getcmdtype()) 10 | let in_cmd_window = s:has_getcmdwintype && !empty(getcmdwintype()) 11 | return in_cmd_line || in_cmd_window 12 | endfunction 13 | 14 | function! s:delayed_checktime() 15 | try 16 | silent checktime 17 | " clearing out 'emergency' events, if the checktime succeeded 18 | augroup focus_gained_checktime 19 | au! 20 | augroup END 21 | catch /E523/ " Not allowed here: silent checktime 22 | catch /E11/ " Invalid in command-line window 23 | " don't clear the augroup, let it fire again when possible 24 | endtry 25 | endfunction 26 | 27 | function! tmux_focus_events#focus_gained() 28 | if !&autoread 29 | return 30 | endif 31 | if cursor_in_cmd_line() 32 | augroup focus_gained_checktime 33 | au! 34 | " perform checktime ASAP when outside cmd line 35 | au * * call delayed_checktime() 36 | augroup END 37 | else 38 | silent checktime 39 | endif 40 | endfunction 41 | -------------------------------------------------------------------------------- /plugin/tmux_focus_events.vim: -------------------------------------------------------------------------------- 1 | if !exists('$TMUX') || has('gui_running') 2 | finish 3 | endif 4 | 5 | if exists('g:loaded_tmux_focus_events') && g:loaded_tmux_focus_events 6 | finish 7 | endif 8 | let g:loaded_tmux_focus_events = 1 9 | 10 | let s:save_cpo = &cpo 11 | set cpo&vim 12 | 13 | function s:do_autocmd(event) 14 | let cmd = getcmdline() 15 | let pos = getcmdpos() 16 | exec 'silent doautocmd ' . a:event . ' %' 17 | call setcmdpos(pos) 18 | return cmd 19 | endfunction 20 | 21 | " This function copied and adapted from https://github.com/sjl/vitality.vim 22 | " If you want to try to understand what is going on, look into comments from 23 | " that plugin. 24 | function! s:restore_focus_events() 25 | let save_screen = "\[?1049h" 26 | let restore_screen = "\[?1049l" 27 | 28 | let tmux_start = "\Ptmux;" 29 | let tmux_end = "\\\" 30 | 31 | " This escape sequence is escaped to get through Tmux without being "eaten" 32 | let enable_focus_reporting = "\[?1004h" 33 | let escaped_enable_focus_reporting = tmux_start 34 | \ . "\" . enable_focus_reporting 35 | \ . tmux_end 36 | \ . enable_focus_reporting 37 | 38 | let disable_focus_reporting = "\[?1004l" 39 | 40 | let &t_ti = escaped_enable_focus_reporting . save_screen 41 | let &t_te = disable_focus_reporting . restore_screen 42 | 43 | " When Tmux 'focus-events' option is on, Tmux will send [O when the 44 | " window loses focus and [I when it gains focus. 45 | exec "set =\[O" 46 | exec "set =\[I" 47 | 48 | nnoremap :silent doautocmd FocusLost % 49 | nnoremap :doautocmd FocusGained % 50 | 51 | onoremap :silent doautocmd FocusLost % 52 | onoremap :silent doautocmd FocusGained % 53 | 54 | vnoremap :silent doautocmd FocusLost %gv 55 | vnoremap :silent doautocmd FocusGained %gv 56 | 57 | inoremap :silent doautocmd FocusLost % 58 | inoremap :silent doautocmd FocusGained % 59 | 60 | if has('terminal') 61 | tnoremap :silent doautocmd FocusLost % 62 | tnoremap :silent doautocmd FocusGained % 63 | endif 64 | 65 | cnoremap edo_autocmd('FocusLost') 66 | cnoremap edo_autocmd('FocusGained') 67 | endfunction 68 | 69 | call restore_focus_events() 70 | 71 | " When '&term' changes values for '', '', '&t_ti' and '&t_te' are 72 | " reset. Below autocmd restores values for those options. 73 | au TermChanged * call restore_focus_events() 74 | 75 | " restore vim 'autoread' functionality 76 | au FocusGained * call tmux_focus_events#focus_gained() 77 | 78 | let &cpo = s:save_cpo 79 | unlet s:save_cpo 80 | -------------------------------------------------------------------------------- /vim_e813.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmux-plugins/vim-tmux-focus-events/b1330e04ffb95ede8e02b2f7df1f238190c67056/vim_e813.png --------------------------------------------------------------------------------