1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-01-24 09:20:06 +08:00
SpaceVim/bundle/vim-dispatch/autoload/dispatch/tmux.vim

131 lines
4.3 KiB
VimL

" 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