-
-
Save ram535/b1b7af6cd7769ec0481eb2eed549ea23 to your computer and use it in GitHub Desktop.
" With this function you can reuse the same terminal in neovim. | |
" You can toggle the terminal and also send a command to the same terminal. | |
let s:monkey_terminal_window = -1 | |
let s:monkey_terminal_buffer = -1 | |
let s:monkey_terminal_job_id = -1 | |
function! MonkeyTerminalOpen() | |
" Check if buffer exists, if not create a window and a buffer | |
if !bufexists(s:monkey_terminal_buffer) | |
" Creates a window call monkey_terminal | |
new monkey_terminal | |
" Moves to the window the right the current one | |
wincmd L | |
let s:monkey_terminal_job_id = termopen($SHELL, { 'detach': 1 }) | |
" Change the name of the buffer to "Terminal 1" | |
silent file Terminal\ 1 | |
" Gets the id of the terminal window | |
let s:monkey_terminal_window = win_getid() | |
let s:monkey_terminal_buffer = bufnr('%') | |
" The buffer of the terminal won't appear in the list of the buffers | |
" when calling :buffers command | |
set nobuflisted | |
else | |
if !win_gotoid(s:monkey_terminal_window) | |
sp | |
" Moves to the window below the current one | |
wincmd L | |
buffer Terminal\ 1 | |
" Gets the id of the terminal window | |
let s:monkey_terminal_window = win_getid() | |
endif | |
endif | |
endfunction | |
function! MonkeyTerminalToggle() | |
if win_gotoid(s:monkey_terminal_window) | |
call MonkeyTerminalClose() | |
else | |
call MonkeyTerminalOpen() | |
endif | |
endfunction | |
function! MonkeyTerminalClose() | |
if win_gotoid(s:monkey_terminal_window) | |
" close the current window | |
hide | |
endif | |
endfunction | |
function! MonkeyTerminalExec(cmd) | |
if !win_gotoid(s:monkey_terminal_window) | |
call MonkeyTerminalOpen() | |
endif | |
" clear current input | |
call jobsend(s:monkey_terminal_job_id, "clear\n") | |
" run cmd | |
call jobsend(s:monkey_terminal_job_id, a:cmd . "\n") | |
normal! G | |
wincmd p | |
endfunction | |
" With this maps you can now toggle the terminal | |
nnoremap <F7> :call MonkeyTerminalToggle()<cr> | |
tnoremap <F7> <C-\><C-n>:call MonkeyTerminalToggle()<cr> | |
" This an example on how specify command with different types of files. | |
augroup go | |
autocmd! | |
autocmd BufRead,BufNewFile *.go set filetype=go | |
autocmd FileType go nnoremap <F5> :call MonkeyTerminalExec('go run ' . expand('%'))<cr> | |
augroup END | |
I have this mapping to resize the windows manually.
nnoremap <Left> :vertical resize +2<CR>
nnoremap <Right> :vertical resize -2<CR>
nnoremap <Up> :resize -2<CR>
nnoremap <Down> :resize +2<CR>
Thanks. Though I'm looking for a way to have it initialize as a certain height, is that possible?
hey guys, how to split below with specify number of row (Ex: 8sp) , please help me
Hey @thewalldao
You can try the solution from @danmikita
https://gist.github.com/ram535/b1b7af6cd7769ec0481eb2eed549ea23#gistcomment-2771529
wincmd J " split below (Move the current window to be at the very bottom)
resize 8 " resize to 8
Any way of getting this to work on Vim as well ? I get an error indicating that termopen is an unkown function.
No clue how make it work in vim, sorry.
Thanks for posting this. I've been using it for some months now.
I included a function to kill all child process of the terminal, if I forgot to do close a REPL.
I call it in the MonkeyTerminalExec function
function! MonkeyTerminalKillChild()
" Close any process that is running in the terminal
call system('kill $(ps --ppid ' . jobpid(s:monkey_terminal_job_id) .' -o pid --no-headers)')
endfunction
I made minor adjustments so that the terminal opens at the bottom and the windows size is saved and restored when being toggled
" With this function you can reuse the same terminal in neovim.
" You can toggle the terminal and also send a command to the same terminal.
let s:monkey_terminal_window = -1
let s:monkey_terminal_buffer = -1
let s:monkey_terminal_job_id = -1
let s:monkey_terminal_window_size = -1
function! MonkeyTerminalOpen()
" Check if buffer exists, if not create a window and a buffer
if !bufexists(s:monkey_terminal_buffer)
" Creates a window call monkey_terminal
new monkey_terminal
" Moves the window to the bottom
wincmd J
resize 15
let s:monkey_terminal_job_id = termopen($SHELL, { 'detach': 1 })
" Change the name of the buffer to "Terminal 1"
silent file Terminal\ 1
" Gets the id of the terminal window
let s:monkey_terminal_window = win_getid()
let s:monkey_terminal_buffer = bufnr('%')
" The buffer of the terminal won't appear in the list of the buffers
" when calling :buffers command
set nobuflisted
else
if !win_gotoid(s:monkey_terminal_window)
sp
" Moves to the window below the current one
wincmd J
execute "resize " . s:monkey_terminal_window_size
buffer Terminal\ 1
" Gets the id of the terminal window
let s:monkey_terminal_window = win_getid()
endif
endif
endfunction
function! MonkeyTerminalToggle()
if win_gotoid(s:monkey_terminal_window)
call MonkeyTerminalClose()
else
call MonkeyTerminalOpen()
endif
endfunction
function! MonkeyTerminalClose()
if win_gotoid(s:monkey_terminal_window)
let s:monkey_terminal_window_size = winheight(s:monkey_terminal_window)
" close the current window
hide
endif
endfunction
function! MonkeyTerminalExec(cmd)
if !win_gotoid(s:monkey_terminal_window)
call MonkeyTerminalOpen()
endif
" clear current input
call jobsend(s:monkey_terminal_job_id, "clear\n")
" run cmd
call jobsend(s:monkey_terminal_job_id, a:cmd . "\n")
normal! G
wincmd p
endfunction
" With this maps you can now toggle the terminal
nnoremap <F7> :call MonkeyTerminalToggle()<cr>
tnoremap <F7> <C-\><C-n>:call MonkeyTerminalToggle()<cr>
nnoremap <M-CR> :call MonkeyTerminalToggle()<cr>
tnoremap <M-CR> <C-\><C-n>:call MonkeyTerminalToggle()<cr>
I added this at the end of terminalopen function
"always enter insert mode
startinsert
I ported the code to lua and made the terminal size reactif to resize
local lua_terminal_window = nil
local lua_terminal_buffer = nil
local lua_terminal_job_id = nil
local function lua_terminal_window_size()
return tonumber(vim.api.nvim_exec("echo &lines", true)) / 4
end
local function LuaTerminalOpen()
if vim.fn.bufexists(lua_terminal_buffer) == 0 then
vim.api.nvim_command("new lua_terminal")
vim.api.nvim_command("wincmd J")
vim.api.nvim_command("resize " .. lua_terminal_window_size())
lua_terminal_job_id = vim.fn.termopen(os.getenv("SHELL"), {
detach = 1
})
vim.api.nvim_command("silent file Terminal 1")
lua_terminal_window = vim.fn.win_getid()
lua_terminal_buffer = vim.fn.bufnr('%')
vim.opt.buflisted = false
else
if vim.fn.win_gotoid(lua_terminal_window) == 0 then
vim.api.nvim_command("sp")
vim.api.nvim_command("wincmd J")
vim.api.nvim_command("resize " .. lua_terminal_window_size())
vim.api.nvim_command("buffer Terminal 1")
lua_terminal_window = vim.fn.win_getid()
end
end
vim.cmd("startinsert")
end
local function LuaTerminalClose()
if vim.fn.win_gotoid(lua_terminal_window) == 1 then
vim.api.nvim_command("hide")
end
end
local function LuaTerminalToggle()
if vim.fn.win_gotoid(lua_terminal_window) == 1 then
LuaTerminalClose()
else
LuaTerminalOpen()
end
end
---@diagnostic disable-next-line: unused-local, unused-function
local function LuaTerminalExec(cmd)
if vim.fn.win_gotoid(lua_terminal_window) == 0 then
LuaTerminalOpen()
end
vim.fn.jobsend(lua_terminal_job_id, 'clear\n')
vim.fn.jobsend(lua_terminal_job_id, cmd .. '\n')
vim.api.nvim_command("normal! G")
vim.api.nvim_command("wincmd p")
end
vim.keymap.set("n", "<space>t", LuaTerminalToggle)
vim.keymap.set("t", "<space>t", LuaTerminalToggle)
For those who doesn't like numbers in terminal, I added
" disables numbers or/and relative numbers just for terminal
setlocal nonumber norelativenumber
I managed to use wincmd J to change it so that the terminal opens on the bottom. How can I adjust height?