Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Calling toggle in quick succession does not respect persist_mode/start_in_insert #522

Open
1 task done
jemag opened this issue Dec 10, 2023 · 2 comments
Open
1 task done

Comments

@jemag
Copy link

jemag commented Dec 10, 2023

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

Calling toggle twice in quick succession will not respect persist_mode/start_in_insert

Expected Behavior

No amount of toggle calling changes the behavior.

Steps To Reproduce

  1. Open neovim with the following minimal config using nvim -u repro.lua somerandomfile:
-- DO NOT change the paths and don't remove the colorscheme
local root = vim.fn.fnamemodify("./.repro", ":p")

-- set stdpaths to use .repro
for _, name in ipairs({ "config", "data", "state", "cache" }) do
  vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name
end

-- bootstrap lazy
local lazypath = root .. "/plugins/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({ "git", "clone", "--filter=blob:none", "https://github.com/folke/lazy.nvim.git", lazypath })
end
vim.opt.runtimepath:prepend(lazypath)
vim.g.mapleader = " "

-- install plugins
local plugins = {
  "folke/tokyonight.nvim",
  -- add any other plugins here
}

local toggleterm_config = {
  "akinsho/toggleterm.nvim",
  config = function()
    require("toggleterm").setup({
      shading_factor = "0",
      hide_numbers = false,
      persist_mode = true,
      start_in_insert = true,
      direction = "float",
      size = function(term)
        if term.direction == "horizontal" then
          return vim.o.lines * 0.5
        elseif term.direction == "vertical" then
          return vim.o.columns * 0.5
        end
      end,
    })

    local term = require("toggleterm.terminal").Terminal
    vim.keymap.set("n", "<leader>tc", function()
      local t = term:new({
        dir = "%:p:h",
        display_name = vim.fn.expand("%:p:h"),
      })
      t:toggle()
    end, { desc = "Term current dir" })
    vim.keymap.set("n", "<leader>t;", function()
      local t = term:new({
        display_name = "default",
      })
      t:toggle()
    end, { desc = "Create term" })
    vim.keymap.set({ "n", "t" }, "<F9>", "<cmd>ToggleTerm<cr>", { desc = "Toggle term" })
    vim.keymap.set({ "n", "t" }, "<F8>", function()
      require("toggleterm").toggle(2)
      require("toggleterm").toggle(1)
    end, { desc = "Toggle term" })
  end,
}

table.insert(plugins, toggleterm_config)
require("lazy").setup(plugins, {
  root = root .. "/plugins",
})

vim.cmd.colorscheme("tokyonight")
-- add anything else here
  1. Create 2 terminals using the provided keybinds (in my case, <leader>tc followed by <leader>t;
  2. Once the 2nd terminal is opened, press <F8>
  3. Notice that while switching back to the first terminal, this terminal will now be in normal mode

Environment

- OS: arch Linux 6.6.3-arch1-1
- neovim version: v0.10.0-dev-38e9875
- Shell: zsh

Anything else?

Here is a video of the Steps to Reproduce section:
https://github.com/akinsho/toggleterm.nvim/assets/7985687/a7c5e75d-609a-4c3b-a2ea-f490add9039c
Note that this behavior will happen also when calling toggle on the same terminal twice in succession as well, e.g.:

      require("toggleterm").toggle(2)
      require("toggleterm").toggle(2)

It also happens if we call the :{count}ToggleTerm twice in quick succession as well.

Why does that matter?

I think being able to call it in quick succession can be useful for some key bindings. For example. I was trying to setup the following keybinds to cycle through my current floating terminals:

local function get_term_index(current_id, terms)
  local idx
  for i, v in ipairs(terms) do
    if v.id == current_id then
      idx = i
    end
  end
  return idx
end

local function go_prev_term()
  local current_id = vim.b.toggle_number
  if current_id == nil then
    return
  end

  local terms = require("toggleterm.terminal").get_all(true)
  local prev_index

  local index = get_term_index(current_id, terms)
  if index > 1 then
    prev_index = index - 1
  else
    prev_index = #terms
  end
  require("toggleterm").toggle(index)
  require("toggleterm").toggle(prev_index)
end

local function go_next_term()
  local current_id = vim.b.toggle_number
  if current_id == nil then
    return
  end

  local terms = require("toggleterm.terminal").get_all(true)
  local next_index

  local index = get_term_index(current_id, terms)
  if index == #terms then
    next_index = 1
  else
    next_index = index + 1
  end
  require("toggleterm").toggle(index)
  require("toggleterm").toggle(next_index)
end

vim.keymap.set({ "n", "t" }, "<F8>", function()
  go_next_term()
end, { desc = "Toggle term" })

vim.keymap.set({ "n", "t" }, "<F7>", function()
  go_prev_term()
end, { desc = "Toggle term" })
@LeFrosch
Copy link

I have a very similar configuration where I can switch between multiple floating terminals and I also have issues with the mode not being consistent. I want every terminal to be back in insert when it is opened. Therefore, I tried calling vim.cmd('startinsert!') in the on_open callback but as far as I can tell this doesn't. As a work around I am using a timer with a very short delay in the callback:

vim.fn.timer_start(1, function()
  vim.cmd('startinsert!')
end)

Maybe this is somehow related.

@haug1
Copy link

haug1 commented Mar 24, 2024

I have a very similar configuration where I can switch between multiple floating terminals and I also have issues with the mode not being consistent. I want every terminal to be back in insert when it is opened. Therefore, I tried calling vim.cmd('startinsert!') in the on_open callback but as far as I can tell this doesn't. As a work around I am using a timer with a very short delay in the callback:

vim.fn.timer_start(1, function()
  vim.cmd('startinsert!')
end)

Maybe this is somehow related.

Was struggling with the same thing. Although not ideal, thanks for the workaround.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants