Simple and highly configurable terminal plugin for neovim.
- Flexible and highly configurable (needs a little creativity and programming ability)
- Manage terminal as buffer
- Multiple terminals
If you are not interested in these, just keep with akinsho/toggleterm.nvim
which is more mature.
---@param bufnr number | nil
---@param on_term_to_open (fun(bufnr: number | nil): boolean) | nil
---@param on_term_opened (fun(bufnr: number, pid: number, channel: number)) | nil
---@param get_cmd (fun(): string) | nil
local open = function(bufnr, on_term_to_open, on_term_opened, get_cmd) end
- Basic usage
Open terminal with require("terminal").open
.
Open terminal in current buffer with
require("terminal").open(0)
.
Open terminal in a new buffer with
require("terminal").open()
.
- Advanced usage
Open terminal anywhere you like.
-- open terminal vertically
local open_vs_terminal = function()
vim.cmd("vsplit")
require("terminal").open(0)
end
-- open terminal horizontally
local open_hs_terminal = function()
-- set height to 50
vim.cmd("50split")
require("terminal").open(0)
end
-- open terminal in float window
local open_float_terminal = function()
-- 'niuiic/core.nvim' required
local core = require("core")
local size = core.win.proportional_size(0.8, 0.6)
local handle = core.win.open_float(0, {
enter = true,
relative = "editor",
width = size.width,
height = size.height,
row = size.row,
col = size.col,
style = "minimal",
border = "rounded",
title = "terminal",
title_pos = "center",
})
require("terminal").open(0)
end
Default configuration here.
local utils = require("terminal.utils")
local config = {
---@type fun(bufnr: number | nil): boolean
on_term_to_open = function()
-- return false to prevent opening terminal
return true
end,
---@type fun(bufnr: number, pid: number, channel: number)
on_term_opened = function() end,
---@type fun(): string
get_cmd = function()
return "terminal"
end,
}
It's recommended to set keymap for terminal buffer. Here is an example.
local terms = {}
local set_line_number = function(show_line_number)
local options = {
"number",
"relativenumber",
}
for _, option in ipairs(options) do
vim.api.nvim_set_option_value(option, show_line_number, {
win = 0,
})
end
end
local set_keymap = function(bufnr)
local modes = { "t", "n" }
for _, mode in ipairs(modes) do
vim.api.nvim_buf_set_keymap(bufnr, mode, "<C-z>", "", {
callback = function()
require("terminal").open()
end,
})
vim.api.nvim_buf_set_keymap(bufnr, mode, "<C-x>", "", {
callback = function()
vim.uv.kill(terms[bufnr], "sigkill")
table.remove(terms, bufnr)
vim.api.nvim_buf_delete(bufnr, {
force = true,
})
end,
})
vim.api.nvim_buf_set_keymap(bufnr, mode, "<C-k>", "", {
callback = function()
-- 'akinsho/bufferline.nvim' required
vim.cmd("BufferLineCycleNext")
end,
})
vim.api.nvim_buf_set_keymap(bufnr, mode, "<C-j>", "", {
callback = function()
vim.cmd("BufferLineCyclePrev")
end,
})
vim.api.nvim_buf_set_keymap(bufnr, mode, "<space>bh", "", {
callback = function()
vim.cmd("BufferLineMovePrev")
end,
})
vim.api.nvim_buf_set_keymap(bufnr, mode, "<space>bl", "", {
callback = function()
vim.cmd("BufferLineMoveNext")
end,
})
vim.api.nvim_buf_set_keymap(bufnr, mode, "<space>bo", "", {
callback = function()
vim.cmd("BufferLinePick")
end,
})
vim.api.nvim_buf_set_keymap(bufnr, mode, "<C-q>", "", {
callback = function()
vim.cmd("Quit")
end,
})
vim.api.nvim_buf_set_keymap(bufnr, mode, "<esc>", "", {
callback = function()
vim.cmd("stopinsert")
end,
})
end
end
return {
config = function()
require("terminal").setup({
on_term_opened = function(bufnr, pid)
vim.api.nvim_set_option_value("filetype", "terminal", {
buf = bufnr,
})
set_line_number(false)
set_keymap(bufnr)
terms[bufnr] = pid
end,
})
vim.api.nvim_create_autocmd({ "BufEnter" }, {
pattern = { "*" },
callback = function(args)
local filetype = vim.api.nvim_get_option_value("filetype", {
buf = args.buf,
})
set_line_number(filetype ~= "terminal")
end,
})
end,
keys = {
{
"<C-z>",
function()
require("terminal").open()
end,
desc = "open terminal",
},
},
}
To launch a job with lua, try this.
on_term_opened = function(bufnr, pid, channel)
local enter = vim.api.nvim_replace_termcodes("<cr>", true, true, true)
vim.defer_fn(function()
vim.api.nvim_feedkeys("node index.js" .. enter, "in", true)
end, 100)
-- or
vim.defer_fn(function()
vim.api.nvim_chan_send(channel, "echo hello" .. enter)
end, 100)
end