" dispatch.vim tmux strategy if exists('g:autoloaded_dispatch_tmux') finish endif let g:autoloaded_dispatch_tmux = 1 let s:waiting = {} let s:make_pane = tempname() function! dispatch#tmux#handle(request) abort let session = get(g:, 'tmux_session', '') if empty($TMUX) && empty(''.session) || !executable('tmux') return 0 endif if !empty(system('tmux has-session -t '.shellescape(session))[0:-2]) return '' endif if a:request.action ==# 'make' if !get(a:request, 'background', 0) && !dispatch#has_callback() && \ !empty(''.session) && session !=# system('tmux display-message -p "#S"')[0:-2] return 0 endif return dispatch#tmux#make(a:request) elseif a:request.action ==# 'start' let command = 'tmux new-window -P -t '.shellescape(session.':') let command .= ' -n '.shellescape(a:request.title) if a:request.background let command .= ' -d' endif let command .= ' ' . shellescape('exec ' . dispatch#isolate( \ a:request, ['TMUX', 'TMUX_PANE'], \ dispatch#set_title(a:request), \ dispatch#prepare_start(a:request))) call system(command) return 1 endif endfunction function! dispatch#tmux#make(request) abort let pipepane = get(g:, 'dispatch_tmux_pipe_pane', 0) \ && a:request.format !~# '%\\[er]' let session = get(g:, 'tmux_session', '') let script = dispatch#isolate(a:request, ['TMUX', 'TMUX_PANE'], \ call('dispatch#prepare_make', [a:request] + \ (pipepane ? [a:request.expanded . '; echo ' . dispatch#status_var() \ . ' > ' . a:request.file . '.complete'] : []))) let title = shellescape(a:request.title) let height = get(g:, 'dispatch_tmux_height', get(g:, 'dispatch_quickfix_height', 10)) if get(a:request, 'background', 0) || (height <= 0 && dispatch#has_callback()) let cmd = 'new-window -d -n '.title elseif has('gui_running') || empty($TMUX) || (!empty(''.session) && session !=# system('tmux display-message -p "#S"')[0:-2]) let cmd = 'new-window -n '.title else let cmd = 'split-window -l '.(height < 0 ? -height : height).' -d' endif let cmd .= ' ' . dispatch#shellescape('-P', '-t', session.':', 'exec ' . script) let filter = 'sed' let uname = system('uname')[0:-2] if uname ==# 'Darwin' let filter = '/usr/bin/sed -l' elseif uname ==# 'Linux' let filter .= ' -u' endif let filter .= " -e \"s/\r\r*$//\" -e \"s/.*\r//\"" let filter .= " -e \"s/\e\\[K//g\" " let filter .= " -e \"s/.*\e\\[2K\e\\[[01]G//g\"" let filter .= " -e \"s/.*\e\\[?25h\e\\[0G//g\"" let filter .= " -e \"s/\e\\[[0-9;]*m//g\"" let filter .= " -e \"s/\017//g\"" let filter .= " > " . a:request.file . "" call system('tmux ' . cmd . '|tee ' . s:make_pane . \ (pipepane ? '|xargs -I {} tmux pipe-pane -t {} '.shellescape(filter) : '')) let pane = s:pane_id(get(readfile(s:make_pane, '', 1), 0, '')) if !empty(pane) let s:waiting[pane] = a:request return 1 endif endfunction function! s:pane_id(pane) abort if a:pane =~# '\.\d\+$' let [window, index] = split(a:pane, '\.\%(\d\+$\)\@=') let out = system('tmux list-panes -F "#P #{pane_id}" -t '.shellescape(window)) let id = matchstr("\n".out, '\n'.index.' \+\zs%\d\+') else let id = system('tmux list-panes -F "#{pane_id}" -t '.shellescape(a:pane))[0:-2] endif return id endfunction function! dispatch#tmux#poll() abort if empty(s:waiting) return endif let panes = split(system('tmux list-panes -a -F "#{pane_id}"'), "\n") for [pane, request] in items(s:waiting) if index(panes, pane) < 0 call remove(s:waiting, pane) call dispatch#complete(request) endif endfor endfunction function! dispatch#tmux#activate(pid) abort let out = system('ps ewww -p '.a:pid) let pane = matchstr(out, 'TMUX_PANE=\zs%\d\+') if empty(pane) return 0 endif let session = get(g:, 'tmux_session', '') if !empty(session) let session = ' -t '.shellescape(session) endif let panes = split(system('tmux list-panes -s -F "#{pane_id}"'.session), "\n") if index(panes, pane) >= 0 call system('tmux select-window -t '.pane.'; tmux select-pane -t '.pane) return !v:shell_error endif endfunction augroup dispatch_tmux autocmd! autocmd VimResized * nested if !dispatch#has_callback() | call dispatch#tmux#poll() | endif augroup END