feat(terminal): auto_close and auto_insert. Closes #965

This commit is contained in:
Folke Lemaitre 2025-02-06 22:14:18 +01:00
parent ba8badfe74
commit bb76cae87e
No known key found for this signature in database
GPG key ID: 41F8B1FBACAE2040

View file

@ -23,7 +23,9 @@ local defaults = {
---@class snacks.terminal.Opts: snacks.terminal.Config
---@field cwd? string
---@field env? table<string, string>
---@field interactive? boolean
---@field auto_close? boolean close the terminal buffer when the process exits
---@field auto_insert? boolean start insert mode when entering the terminal buffer
---@field interactive? boolean shortcut for `auto_close` and `auto_insert` (default: true)
Snacks.config.style("terminal", {
bo = {
@ -73,15 +75,19 @@ function M.open(cmd, opts)
opts = Snacks.config.get("terminal", defaults --[[@as snacks.terminal.Opts]], opts)
opts.win = Snacks.win.resolve("terminal", {
position = cmd and "float" or "bottom",
}, opts.win)
}, opts.win, { show = false })
opts = vim.deepcopy(opts)
opts.win.wo.winbar = opts.win.wo.winbar or (opts.win.position == "float" and "" or (id .. ": %{b:term_title}"))
if opts.override then
return opts.override(cmd, opts)
end
local on_buf = opts.win and opts.win.on_buf
local interactive = opts.interactive ~= false
local auto_insert = opts.auto_insert or (opts.auto_insert == nil and interactive)
local auto_close = opts.auto_close or (opts.auto_close == nil and interactive)
local on_buf = opts.win and opts.win.on_buf
---@param self snacks.terminal
opts.win.on_buf = function(self)
self.cmd = cmd
@ -91,8 +97,41 @@ function M.open(cmd, opts)
end
end
local on_win = opts.win and opts.win.on_win
---@param self snacks.terminal
opts.win.on_win = function(self)
if auto_insert and vim.api.nvim_get_current_buf() == self.buf then
vim.cmd.startinsert()
end
if on_win then
on_win(self)
end
end
local terminal = Snacks.win(opts.win)
if auto_insert then
terminal:on("BufEnter", function()
vim.cmd.startinsert()
end, { buf = true })
end
if auto_close then
terminal:on("TermClose", function()
if type(vim.v.event) == "table" and vim.v.event.status ~= 0 then
Snacks.notify.error("Terminal exited with code " .. vim.v.event.status .. ".\nCheck for any errors.")
return
end
terminal:close()
vim.cmd.checktime()
end, { buf = true })
end
terminal:on("ExitPre", function()
terminal:close()
end)
terminal:show()
vim.api.nvim_buf_call(terminal.buf, function()
local term_opts = {
cwd = opts.cwd,
@ -104,30 +143,6 @@ function M.open(cmd, opts)
)
end)
if opts.interactive ~= false then
vim.cmd.startinsert()
vim.api.nvim_create_autocmd("TermClose", {
once = true,
buffer = terminal.buf,
callback = function()
if type(vim.v.event) == "table" and vim.v.event.status ~= 0 then
Snacks.notify.error("Terminal exited with code " .. vim.v.event.status .. ".\nCheck for any errors.")
return
end
terminal:close()
vim.cmd.checktime()
end,
})
vim.api.nvim_create_autocmd("BufEnter", {
buffer = terminal.buf,
callback = function()
vim.cmd.startinsert()
end,
})
terminal:on("ExitPre", function()
terminal:close()
end)
end
vim.cmd("noh")
return terminal
end