numToStr / FTerm.nvim

:fire: No-nonsense floating terminal plugin for neovim :fire:
MIT License
721 stars 24 forks source link

toggle custom terminal: close the toggle #78

Open gennaro-tedesco opened 1 year ago

gennaro-tedesco commented 1 year ago

First of all thank you very much for the great plugin!

I am creating a terminal instance where a pass a certain custom command as per the docs: in particular a minimal reproducible example can be thought of as

local function hello()
  return fterm:new({ cmd = 'echo "hello"' })
end

vim.keymap.set('n', '<A-g>', function()
    hello():toggle()
end)

This works fine when toggling the terminal in normal mode, however whilst in terminal mode (with the command already toggled and the custom terminal already active) the only way to close it is via q rather than via <A-g> again. If I explicitly define a command in terminal mode as shown

vim.keymap.set('t', '<A-g>', '<C-\\><C-n><CMD>lua hello()<CR>')

I get exceptions of "attempt to index a boolean value" (also if I fully qualify the path to the custom function fully requiring the whole module). I wonder if the object fterm:new() really returns a toggleable instance, or perhaps I am merely making silly grammar mistakes while defining the keymap in terminal mode?

benyn commented 1 year ago

I was getting a very similar issue, but I managed to make the following work. Basically, I'm creating an autocmd that creates a keymap for each filetype, which I'm using as a proxy for each FTerm instance.

local function create_autocmd(pattern, key, term)
  vim.api.nvim_create_autocmd("FileType", {
    pattern = pattern,
    callback = function(event)
      local t = term
      vim.keymap.set("t", key, function() t:close() end, { buffer = event.buf, silent = true })
    end,
  })
end

I use <C-Bslash> to toggle the default terminal like below (keymap for n mode is created separately):

local fterm = require("FTerm")
fterm.setup(opts)
create_close_autocmd("FTerm", "<C-Bslash>", fterm)

And I use <C-g> to toggle the GitUI terminal instance, which is created when the key is first used.

local gitui = nil
local function toggleGitUI()
  if gitui == nil then
    local filetype = "FTerm_GitUI"
    gitui = require("FTerm"):new({
      ft = filetype,
      cmd = "gitui",
      dimensions = {
        height = 0.9,
        width = 0.9,
      },
    })
    create_close_autocmd(filetype, "<C-g>", gitui)
  end
  gitui:toggle()
end

I'm creating keymaps for n and t modes separately only because I used lazy.nvim to create the keymaps for Normal mode, and if you don't need that triggering, you could probably simplify this. Hope this helps.