ryanmsnyder / toggleterm-manager.nvim

A Telescope extension to manage Toggleterm's terminals in NeoVim
GNU General Public License v3.0
64 stars 4 forks source link

Toggle full size terminal #2

Closed sandangel closed 7 months ago

sandangel commented 9 months ago

Hi, thanks for the great plugin. I wonder is it possible to toggle the current terminal to fullsize with this plugin? Sometimes I feel the toggle term window is a bit small so want to have it fullsize window while I'm presenting. After I finish, I like to toggle it to be the normal size again.

ryanmsnyder commented 9 months ago

Hi @sandangel, to get a larger terminal, you'll have to change your toggleterm.nvim configuration. There's a size property that you can pass a number or a function to. I believe the default value is 20. Play around with some larger values:

require("toggleterm").setup {
  size = 60
}
sandangel commented 9 months ago

Hi, thanks for sharing. I mean is there a way to toggle fullsize for current terminal, not a fixed size if we set in settings.

ryanmsnyder commented 9 months ago

I want to make sure I understand your use case: so you're hoping to map an action in toggleterm-manager that opens an already existing toggleterm terminal in fullscreen (even if the terminal was originally a smaller size)?

sandangel commented 9 months ago

@ryanmsnyder yeah. that is correct, sorry for not being clear.

ryanmsnyder commented 9 months ago

@sandangel I'll see if I can create a custom action for this

ryanmsnyder commented 9 months ago

@sandangel give the below code a try and let me know if this is what you were thinking.

local toggleterm_manager = require "toggleterm-manager"
local telescope_actions = require "telescope.actions"
local actions_state = require "telescope.actions.state"
local toggleterm_ui = require "toggleterm.ui"
local toggleterm_config = require "toggleterm.config"

local actions = toggleterm_manager.actions

-- Create autocmd that essentially overwrites the direction/size that toggleterm saves when the term buffer exits.
-- Without this, when creating additional terminal buffers, toggleterm will create a split at the maximum
-- size because it saved the size of the full screen terminal buffer when it was exited.
local function leave_full_term_autocmd(prompt_bufnr)
  vim.api.nvim_create_augroup("SaveDirOnLeaveFullTerm", {})
  vim.api.nvim_create_autocmd("BufLeave", {
    buffer = prompt_bufnr,
    group = "SaveDirOnLeaveFullTerm",
    nested = true,
    once = true,
    callback = function()
      -- save the original size and direction that was set in the toggleterm config
      toggleterm_ui.save_direction_size(toggleterm_config.direction, toggleterm_config.size)
    end,
  })
end

local function toggle_full_term(prompt_bufnr, exit_on_action)
  local selection = actions_state.get_selected_entry()
  if selection == nil then
    return
  end

  local term = selection.value

  telescope_actions.close(prompt_bufnr)

  -- open term first so `only` command can be executed on the buffer
  term:open()
  vim.cmd "only"

  -- toggleterm_ui.save_direction_size(toggleterm_config.direction, toggleterm_config.size)
  leave_full_term_autocmd(term.bufnr)
end

toggleterm_manager.setup {
  mappings = {
    i = {
      ["<C-j>"] = { action = toggle_full_term, exit_on_action = true },
    },
  },
}

I still need to work out a couple of things.

There's a bit of a bug when following these steps:

  1. create two Toggleterm terminals within toggleterm-manager
  2. execute the toggle_full_term action on one of the terminals
  3. in the full screen terminal that was just opened, execute the exit command to close/delete the terminal buffer
  4. open toggleterm-manager again and execute the toggle_full_term action on the other terminal
  5. repeat step 3

This throws the following error toggleterm error:

...al/share/nvim/lazy/toggleterm.nvim/lua/toggleterm/ui.lua:350: Vim:E444: Cannot close last window
stack traceback:
^I[C]: in function 'nvim_win_close'
^I...al/share/nvim/lazy/toggleterm.nvim/lua/toggleterm/ui.lua:350: in function 'close_split'
^I...al/share/nvim/lazy/toggleterm.nvim/lua/toggleterm/ui.lua:386: in function 'close'
^I...re/nvim/lazy/toggleterm.nvim/lua/toggleterm/terminal.lua:277: in function 'close'
^I...re/nvim/lazy/toggleterm.nvim/lua/toggleterm/terminal.lua:350: in function <...re/nvim/lazy/toggleterm.nvim/lua/toggleterm/terminal.lua:347>

Not sure why it doesn't throw an error after executing exit on the first terminal but I think it has to do with processing that's done by toggleterm when a terminal buffer is deleted.

Anyway, let me know if this action is what you had in mind. I can tweak it for your use case. I'll also try to iron out the bugs.

sandangel commented 9 months ago

Nice, I will give it a try

ryanmsnyder commented 9 months ago

Here's a slightly more concise solution. Some things to note:

local toggleterm_manager = require "toggleterm-manager"
local telescope_actions = require "telescope.actions"
local actions_state = require "telescope.actions.state"
local toggleterm_ui = require "toggleterm.ui"
local toggleterm_config = require "toggleterm.config"

local actions = toggleterm_manager.actions

local function toggle_full_term(prompt_bufnr)
  local selection = actions_state.get_selected_entry()
  if selection == nil then
    return
  end

  local term = selection.value

  telescope_actions.close(prompt_bufnr)

  -- open term first so `only` command can be executed on the buffer
  term:open()
  toggleterm_manager.utils.start_insert_mode()
  vim.cmd "only"

  -- toggleterm runs a term's on_exit function before continuing with its exit processing.
  -- delete the buffer and close the window (in that order) before toggleterm can attempt to close the window (before
  -- it attempts to the delete the buffer), which throws an error since neovim won't allow the only open window
  -- from being closed with vim.api.nvim_win_close
  term.on_exit = function()
    vim.api.nvim_buf_delete(term.bufnr, { force = true })
    vim.api.nvim_win_close(term.window)
  end
end

toggleterm_manager.setup {
  mappings = {
    i = {
      ["<C-j>"] = { action = toggle_full_term },
    },
  },
}
sandangel commented 9 months ago

Is it possible to introduce layout, so when create new terminal buffer, we still keep the layout. The layout can have fullscreen layout. So toggle zoom will become more like changing between layouts. Similar to kitty layout approach. Wfyt?

ryanmsnyder commented 9 months ago

I don't use kitty so I'm unfamiliar with the layout approach you're referring to. Are you able to provide screenshots as an example?

sandangel commented 9 months ago

hi @ryanmsnyder thank you so much. I think this document on kitty will better explain how layouts work: https://sw.kovidgoyal.net/kitty/layouts/

I just wonder if we can do this in neovim itself.