From 39b14c400653f320133b3f8c65cdb612e42f9ca1 Mon Sep 17 00:00:00 2001 From: Iordanis Petkakis <12776461+dpetka2001@users.noreply.github.com> Date: Fri, 17 Oct 2025 22:14:56 +0300 Subject: [PATCH] feat(terminal): minor improvements for user experience (#2276) ## Description I was trying to create a simple `select` picker to choose terminals to open. With the current implementation only the fields `cmd` and `id` are exposed. `cwd` and `env` are not which are used to get the terminal id as well. `M.list()` uses `vim.tbl_filter` which turns `terminals` into a list removing the keys terminal ids. Even if that was not the case (i.e using a normal `for` loop to add to `terminals`) the keys would be a string due to `vim.inspect` and one would have to use patterns to extract information from them. It's easier to just add `cwd` and `env` to `vim.b[buf].snacks_terminal` to have that information available and be easier for users to manipulate which terminal they want to choose and open. Also added `opts.count` as an option to be able to programmatically choose the terminal with exactly the same options when it was created, so one can just do ```lua local term = vim.b[buf].snacks_terminal Snacks.terminal(term.cmd, { cwd = term.cwd, env = term.env, count = term.id }) ``` to programmatically invoke a certain terminal. ## Related Issue(s) Solves my issue and #2271 as well. ## Screenshots --- lua/snacks/terminal.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lua/snacks/terminal.lua b/lua/snacks/terminal.lua index 40b39050..4d9cd715 100644 --- a/lua/snacks/terminal.lua +++ b/lua/snacks/terminal.lua @@ -22,6 +22,7 @@ local defaults = { ---@class snacks.terminal.Opts: snacks.terminal.Config ---@field cwd? string +---@field count? integer ---@field env? table ---@field start_insert? boolean start insert mode when starting the terminal ---@field auto_insert? boolean start insert mode when entering the terminal buffer @@ -82,8 +83,8 @@ end ---@param cmd? string | string[] ---@param opts? snacks.terminal.Opts function M.open(cmd, opts) - local id = vim.v.count1 opts = Snacks.config.get("terminal", defaults --[[@as snacks.terminal.Opts]], opts) + local id = opts.count or vim.v.count1 opts.win = Snacks.win.resolve("terminal", { position = cmd and "float" or "bottom", }, opts.win, { show = false }) @@ -104,7 +105,7 @@ function M.open(cmd, opts) ---@param self snacks.terminal opts.win.on_buf = function(self) self.cmd = cmd - vim.b[self.buf].snacks_terminal = { cmd = cmd, id = id } + vim.b[self.buf].snacks_terminal = { cmd = cmd, id = id, cwd = opts.cwd, env = opts.env } if on_buf then on_buf(self) end @@ -171,7 +172,7 @@ end ---@return snacks.win? terminal, boolean? created function M.get(cmd, opts) opts = opts or {} - local id = vim.inspect({ cmd = cmd, cwd = opts.cwd, env = opts.env, count = vim.v.count1 }) + local id = vim.inspect({ cmd = cmd, cwd = opts.cwd, env = opts.env, count = opts.count or vim.v.count1 }) local created = false if not (terminals[id] and terminals[id]:buf_valid()) and (opts.create ~= false) then local ret = M.open(cmd, opts)