diff --git a/README.md b/README.md index 6700ce5..b56c89c 100644 --- a/README.md +++ b/README.md @@ -251,6 +251,16 @@ Screenshot ![btop](https://user-images.githubusercontent.com/24727447/135802042-afe83ad0-e044-4ba6-bd19-0a75fdeff441.png "btop w/ fterm") +Custom terminals support the same methods as the default one: `open()`, `close()`, `toggle()`, `run({cmd})` and `exit()`. Use `exit()` when you want to kill the underlying process instead of just hiding the window. + +```lua +-- Hides the window, the process keeps running +btop:close() + +-- Kills the process and deletes the terminal buffer +btop:exit() +``` + ### 💐 Credits - [vim-floaterm](https://github.com/voldikss/vim-floaterm) for the inspiration diff --git a/lua/FTerm/init.lua b/lua/FTerm/init.lua index d13133a..61144ea 100644 --- a/lua/FTerm/init.lua +++ b/lua/FTerm/init.lua @@ -29,7 +29,7 @@ end ---Exits the terminal session function M.exit() - t:close(true) + t:exit() end ---Toggles the default terminal diff --git a/lua/FTerm/terminal.lua b/lua/FTerm/terminal.lua index c521b8b..357d009 100644 --- a/lua/FTerm/terminal.lua +++ b/lua/FTerm/terminal.lua @@ -143,7 +143,8 @@ end ---@return Term function Term:open_term() -- NOTE: `termopen` will fails if the current buffer is modified - self.terminal = fn.termopen(U.is_cmd(self.config.cmd), { + self.terminal = fn.jobstart(U.get_cmd(self.config.cmd), { + term = true, clear_env = self.config.clear_env, env = self.config.env, on_stdout = self.config.on_stdout, @@ -183,31 +184,44 @@ function Term:open() end ---Term:close does all the magic of closing terminal and clearing the buffers/windows ----@param force? boolean If true, kill the terminal otherwise hide it ---@return Term -function Term:close(force) +function Term:close() if not U.is_win_valid(self.win) then return self end - A.nvim_win_close(self.win, {}) + A.nvim_win_close(self.win, true) self.win = nil - if force then - if U.is_buf_valid(self.buf) then - A.nvim_buf_delete(self.buf, { force = true }) - end + self:restore_cursor() - fn.jobstop(self.terminal) + return self +end - self.buf = nil - self.terminal = nil +local buffer_cleanup = function(buf) + -- jobstop and buf_delete can make a race condition as jobstop can already + -- delete the buffer + vim.defer_fn(function() + if U.is_buf_valid(buf) then + A.nvim_buf_delete(buf, { force = true }) end + end, 5000) +end - self:restore_cursor() +-- Careful, jobstop (and nvim_buf_delete on a buffer with a job) have an +-- extremely odd behaviour. If you call it at the same time as when you create a +-- terminal they kill both the old and the new terminal (nvim has a race +-- condition I guess). +function Term:exit() + self:close() - return self + fn.jobstop(self.terminal) + + buffer_cleanup(self.buf) + + self.buf = nil + self.terminal = nil end ---Term:toggle is used to toggle the terminal window @@ -229,7 +243,7 @@ end function Term:run(command) self:open() - local exec = U.is_cmd(command) + local exec = U.get_cmd(command) A.nvim_chan_send( self.terminal, diff --git a/lua/FTerm/utils.lua b/lua/FTerm/utils.lua index 08e6860..6f7aee4 100644 --- a/lua/FTerm/utils.lua +++ b/lua/FTerm/utils.lua @@ -85,7 +85,7 @@ end ---Creates a valid command from user's input ---@param cmd Command ---@return Command -function U.is_cmd(cmd) +function U.get_cmd(cmd) return type(cmd) == 'function' and cmd() or cmd end