diff --git a/README.md b/README.md index 54733f3d..ed543b9b 100644 --- a/README.md +++ b/README.md @@ -126,7 +126,7 @@ I'm also going to be pretty conservative about what I add. This plugin must be explicitly enabled by using `require("toggleterm").setup{}` -Setting the `open_mapping` key to use for toggling the terminal(s) will set up mappings for _normal_ mode. The `open_mapping` can be a key string or an array of key strings. +Setting the `open_mapping` key to use for toggling the terminal(s) will set up mappings for _normal_ mode. The `open_mapping` can be a key string or an array of key strings. If you prefix the mapping with a number that particular terminal will be opened. Otherwise if a prefix is not set, then the last toggled terminal will be opened. In case there are multiple terminals opened they'll all be closed, and on the next mapping key they'll be restored. If you set the `insert_mappings` key to `true`, the mapping will also take effect in insert mode; similarly setting `terminal_mappings` to `true` will have the mappings take effect in the opened terminal. @@ -195,6 +195,7 @@ require("toggleterm").setup{ persist_mode = true, -- if set to true (default) the previous terminal mode will be remembered direction = 'vertical' | 'horizontal' | 'tab' | 'float', close_on_exit = true, -- close the terminal window when the process exits + close_on_exit_success = true, -- close the terminal window only when the process exits with 0 clear_env = false, -- use only environmental variables from `env`, passed to jobstart() -- Change the default shell. Can be a string or a function returning a string shell = vim.o.shell, @@ -448,6 +449,7 @@ Terminal:new { direction = string -- the layout for the terminal, same as the main config options dir = string -- the directory for the terminal close_on_exit = bool -- close the terminal window when the process exits + close_on_exit_success = bool -- close the terminal window only when the process exits with 0 highlights = table -- a table with highlights env = table -- key:value table with environmental variables passed to jobstart() clear_env = bool -- use only environmental variables from `env`, passed to jobstart() diff --git a/doc/toggleterm.txt b/doc/toggleterm.txt index 9a072b01..0d6716fa 100644 --- a/doc/toggleterm.txt +++ b/doc/toggleterm.txt @@ -182,6 +182,7 @@ what options are available. It is not written to be used as is. persist_mode = true, -- if set to true (default) the previous terminal mode will be remembered direction = 'vertical' | 'horizontal' | 'tab' | 'float', close_on_exit = true, -- close the terminal window when the process exits + close_on_exit_success = true, -- close the terminal window only when the process exits with 0 clear_env = false, -- use only environmental variables from `env`, passed to jobstart() -- Change the default shell. Can be a string or a function returning a string shell = vim.o.shell, @@ -451,6 +452,7 @@ Each terminal can take the following arguments: direction = string -- the layout for the terminal, same as the main config options dir = string -- the directory for the terminal close_on_exit = bool -- close the terminal window when the process exits + close_on_exit_success = bool, -- close the terminal window only when the process exits with 0 highlights = table -- a table with highlights env = table -- key:value table with environmental variables passed to jobstart() clear_env = bool -- use only environmental variables from `env`, passed to jobstart() diff --git a/lua/toggleterm/config.lua b/lua/toggleterm/config.lua index 736d8cf8..cb115781 100644 --- a/lua/toggleterm/config.lua +++ b/lua/toggleterm/config.lua @@ -29,6 +29,7 @@ local function shade(color, factor) return colors.shade_color(color, factor) end --- @field persist_size boolean --- @field persist_mode boolean --- @field close_on_exit boolean +--- @field close_on_exit_success boolean --- @field clear_env boolean --- @field direction '"horizontal"' | '"vertical"' | '"float"' --- @field shading_factor number @@ -54,6 +55,7 @@ local config = { persist_size = true, persist_mode = true, close_on_exit = true, + close_on_exit_success = true, clear_env = false, direction = "horizontal", shading_factor = constants.shading_amount, diff --git a/lua/toggleterm/terminal.lua b/lua/toggleterm/terminal.lua index 19231c40..18d90d6a 100644 --- a/lua/toggleterm/terminal.lua +++ b/lua/toggleterm/terminal.lua @@ -64,6 +64,7 @@ local terminals = {} --- @field display_name string? --- @field hidden boolean? whether or not to include this terminal in the terminals list --- @field close_on_exit boolean? whether or not to close the terminal window when the process exits +--- @field close_on_exit_success boolean? whether or not to close the terminal window only when the process exits with 0 --- @field auto_scroll boolean? whether or not to scroll down on terminal output --- @field float_opts table? --- @field on_stdout fun(t: Terminal, job: number, data: string[]?, name: string?)? @@ -87,6 +88,7 @@ local terminals = {} --- @field count number the count that triggers that specific terminal --- @field hidden boolean whether or not to include this terminal in the terminals list --- @field close_on_exit boolean? whether or not to close the terminal window when the process exits +--- @field close_on_exit_success boolean? whether or not to close the terminal window only when the process exits with 0 --- @field auto_scroll boolean? whether or not to scroll down on terminal output --- @field float_opts table? --- @field display_name string? @@ -220,6 +222,9 @@ function Terminal:new(term) term.on_exit = vim.F.if_nil(term.on_exit, conf.on_exit) term.__state = { mode = "?" } if term.close_on_exit == nil then term.close_on_exit = conf.close_on_exit end + if term.close_on_exit_success == nil then + term.close_on_exit_success = conf.close_on_exit_success + end -- Add the newly created terminal to the list of all terminals ---@diagnostic disable-next-line: return-type-mismatch return setmetatable(term, self) @@ -360,13 +365,17 @@ end --- Handle when a terminal process exits ---@param term Terminal local function __handle_exit(term) - return function(...) - if term.on_exit then term:on_exit(...) end - if term.close_on_exit then - term:close() - if api.nvim_buf_is_loaded(term.bufnr) then - api.nvim_buf_delete(term.bufnr, { force = true }) - end + local function close() + term:close() + if api.nvim_buf_is_loaded(term.bufnr) then api.nvim_buf_delete(term.bufnr, { force = true }) end + end + + return function(job, exit_code, name) + if term.on_exit then term:on_exit(job, exit_code, name) end + if term.close_on_exit_success then + if exit_code == 0 then close() end + elseif term.close_on_exit then + close() end end end