Skip to content

Simple and highly configurable terminal plugin for neovim.

License

Notifications You must be signed in to change notification settings

niuiic/terminal.nvim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 

Repository files navigation

terminal.nvim

Simple and highly configurable terminal plugin for neovim.

More neovim plugins

Why this plugin

  • 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.

Usage

---@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

Config

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

About

Simple and highly configurable terminal plugin for neovim.

Topics

Resources

License

Stars

Watchers

Forks

Languages