├── LICENSE ├── README.md └── plugin └── vimtmuxclipboard.vim /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2023 roxma@qq.com 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | “Software”), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # vim-tmux-clipboard 3 | 4 | Things get messy when I need to copy lines of text from vim into tmux's 5 | clipboard, especially when multiple split-windows are opened. So I created this 6 | super simple plugin, which provides seamless integration for vim and tmux's 7 | clipboard. 8 | 9 | 10 | vim-tmux-clipboard automatically copy yanked text into tmux's clipboard, and 11 | copy tmux's clipboard content into vim's quote(`"`) register, known as the unnamed 12 | register. It also makes multiple vim processes on top of the same tmux session 13 | act like they're sharing the same clipboard. 14 | 15 | 16 | ## Requirements 17 | 18 | - add `set -g focus-events on` to your `tmux.conf`. 19 | - [vim-tmux-focus-events](https://github.com/tmux-plugins/vim-tmux-focus-events) for vim users. 20 | - [neovim](https://github.com/neovim/neovim) or vim above 8.0.1394 is 21 | recommended for `TextYankPost` event, which is required for `It also makes 22 | multiple vim processes on top of the same tmux session act like they're 23 | sharing the same clipboard`. 24 | 25 | ## Options 26 | 27 | - `g:vim_tmux_clipboard#loadb_option` see [#20](https://github.com/roxma/vim-tmux-clipboard/pull/20) 28 | 29 | ## Demo 30 | 31 | [![asciicast](https://asciinema.org/a/7qzb7c12ykv3kcleo4jgrl2jy.png)](https://asciinema.org/a/7qzb7c12ykv3kcleo4jgrl2jy) 32 | 33 | 34 | -------------------------------------------------------------------------------- /plugin/vimtmuxclipboard.vim: -------------------------------------------------------------------------------- 1 | 2 | let g:vim_tmux_clipboard#loadb_option = get(g:, 'vim_tmux_clipboard#loadb_option', '') 3 | 4 | func! s:TmuxBufferName() 5 | let l:list = systemlist('tmux list-buffers -F"#{buffer_name}"') 6 | if len(l:list)==0 7 | return "" 8 | else 9 | return l:list[0] 10 | endif 11 | endfunc 12 | 13 | function! s:on_stdout(job_id, data, event) 14 | let @" = join(a:data, "\n") 15 | endfunction 16 | 17 | func! s:AsyncTmuxBuffer() 18 | call jobstart('tmux show-buffer', {'on_stdout': function('s:on_stdout'), 'stdout_buffered': 1}) 19 | endfunc 20 | 21 | func! s:TmuxBuffer() 22 | return system('tmux show-buffer') 23 | endfunc 24 | 25 | func! s:Enable() 26 | 27 | if $TMUX=='' 28 | " not in tmux session 29 | return 30 | endif 31 | 32 | let s:lastbname="" 33 | 34 | " if support TextYankPost 35 | if exists('##TextYankPost')==1 36 | " @" 37 | augroup vimtmuxclipboard 38 | autocmd! 39 | autocmd FocusLost * call s:update_from_tmux() 40 | autocmd FocusGained * call s:update_from_tmux() 41 | autocmd TextYankPost * silent! call system('tmux loadb ' . g:vim_tmux_clipboard#loadb_option . ' -',join(v:event["regcontents"],"\n")) 42 | augroup END 43 | if exists('*jobstart')==1 " Only supported on Neovim 44 | call s:AsyncTmuxBuffer() 45 | else 46 | let @" = s:TmuxBuffer() 47 | endif 48 | else 49 | " vim doesn't support TextYankPost event 50 | " This is a workaround for vim 51 | augroup vimtmuxclipboard 52 | autocmd! 53 | autocmd FocusLost * silent! call system('tmux loadb ' . g:vim_tmux_clipboard#loadb_option . ' -',@") 54 | autocmd FocusGained * let @" = s:TmuxBuffer() 55 | augroup END 56 | let @" = s:TmuxBuffer() 57 | endif 58 | 59 | endfunc 60 | 61 | func! s:update_from_tmux() 62 | let buffer_name = s:TmuxBufferName() 63 | if s:lastbname != buffer_name 64 | let @" = s:TmuxBuffer() 65 | endif 66 | let s:lastbname=s:TmuxBufferName() 67 | endfunc 68 | 69 | call s:Enable() 70 | 71 | " " workaround for this bug 72 | " if shellescape("\n")=="'\\\n'" 73 | " let l:s=substitute(l:s,'\\\n',"\n","g") 74 | " let g:tmp_s=substitute(l:s,'\\\n',"\n","g") 75 | " "); 76 | " let g:tmp_cmd='tmux set-buffer ' . l:s 77 | " endif 78 | " silent! call system('tmux loadb -w -',l:s) 79 | --------------------------------------------------------------------------------