Commit afa1901f authored by Dom Sekotill's avatar Dom Sekotill
Browse files

Add a toggle-able terminal in Vim, unfinished

parent c968edcb
Loading
Loading
Loading
Loading
+109 −0
Original line number Diff line number Diff line
""
" Toggle terminal buffers from hotkeys
""

function! kodo#toggleterm#Terminal(cmd)
	let term = {}
	let term.origin_buffer = v:null
	let term.window = v:null
	let term.was_new = v:null
	let term.cmd = type(a:cmd) == v:t_list ? a:cmd :
	             \      a:cmd  == v:null   ? [ &shell ] :
	             \                           [ &shell, '-c', string(a:cmd) ]

	" Expand (show) the terminal, optionally in a new window
	" If a new window is requested it is opened by spliting, which obeys the […] 
	" and […] settings.
	function term.expand(new_win)
		if self.window != v:null
			call self.collapse()
		endif
		let self.was_new = a:new_win
		if a:new_win
			" Open and switch to a new window
			silent execute 'sbuffer +startinsert' self.buffer
			" let b:toggle_term = self
			" augroup toggleterm
			" 	au! WinLeave <buffer>
			" 	au WinLeave <buffer> call b:toggle_term.collapse()
			" augroup END
		else
			silent execute 'buffer +startinsert' self.buffer
		endif

		let self.window = win_getid()
		let self.origin_buffer = a:new_win ? v:null : bufnr('')

		if has('nvim') && !has('nvim-0.4')
			" Hack to fix terminal resizing bug
			silent execute 'buffer' bufnr('#')
			redraw
			silent execute 'buffer +startinsert' self.buffer
		endif
	endfunction

	" Collapse (hide) the terminal by restoring any origin buffer if there is 
	" one, else closing the terminal window.
	function term.collapse()
		" silent execute 'au! toggleterm *' self.buffer
		let window = win_getid()
		if !win_gotoid(self.window)
			echoerr "Toggle-terminal window not found, ignoring"
		else
			if self.was_new
				close
			elseif bufnr('') == self.buffer
				silent execute 'buffer' self.origin_buffer
			else
				echoerr "Buffer in toggle-terminal window changed, ignoring"
			endif
			call win_gotoid(window)
		endif
		let self.window = v:null
	endfunction

	function term.toggle(new_win)
		if self.window == win_getid()
			call self.collapse()
		else
			call self.expand(a:new_win)
		endif
	endfunction

	" termopen() on_exit handler
	" Restores any origin buffer and cleans up the terminal buffer
	function term.on_exit(jobid, data, event)
		if self.origin_buffer != v:null
			silent execute 'buffer' self.origin_buffer
		endif
		silent execute 'bdelete!' self.buffer
		let self.buffer = v:null
	endfunction

	" Create the terminal buffer
	let origin = bufnr('')
	enew
	let term.buffer =  bufnr('')

	if term.buffer == origin && origin != 1
		echoerr "New buffer appears to have replaced old buffer?"
	endif

	" Hide from the buffer list
	setl nobuflisted

	" Start the terminal job
	let term.job = termopen(term.cmd, term)

	silent execute 'buffer' origin

	if term.job > 0
		return term
	elseif term.job == -1
		echoerr "Not found or executable:" term.cmd[0]
	else
		throw "Failed to open a new terminal; returned: " + term.job
	endif

	return v:null
endfunction
+22 −0
Original line number Diff line number Diff line
let g:TermToggleOpenNewWindow = 1
let s:hot_terms = {}

function s:toggle(num)
	if !has_key(s:hot_terms, a:num)
		let s:hot_terms[a:num] = kodo#toggleterm#Terminal(v:null) 
	endif
	call s:hot_terms[a:num].toggle(g:TermToggleOpenNewWindow)

	" command! -nargs=0 TermToggle :call <SID>:global_term_list[<SID>:global_term_cur].toggle(g:TermToggleOpenNewWindow)
endfunction

command -nargs=1 TermToggle :call s:toggle(<args>)

nnoremap <silent> <F6> <Esc>:TermToggle 0<CR>
tnoremap <silent> <F6> <C-\><C-n>:TermToggle 0<CR>

nnoremap <silent> <F7> <Esc>:TermToggle 1<CR>
tnoremap <silent> <F7> <C-\><C-n>:TermToggle 1<CR>

nnoremap <silent> <F8> <Esc>:TermToggle 2<CR>
tnoremap <silent> <F8> <C-\><C-n>:TermToggle 2<CR>