willothy / flatten.nvim

Open files and command output from wezterm, kitty, and neovim terminals in your current neovim instance
https://luarocks.org/modules/willothy/flatten.nvim
MIT License
473 stars 13 forks source link

Strange behavior when using git rebase in toggleterm with flatten.nvim #51

Closed Bekaboo closed 1 year ago

Bekaboo commented 1 year ago

Describe the bug When using git rebase -i HEAD^^ in toggleterm with flatten.nvim installed, after closing the reword buffer, :TogglTerm will make the terminal buffer occupy both windows instead of just the the bottom window.

Minimal config

local tmp = vim.env.TMPDIR
  or vim.env.TEMPDIR
  or vim.env.TMP
  or vim.env.TEMP
  or '/tmp'
local data = tmp .. '/' .. (vim.env.NVIM_APPNAME or 'nvim')
local packages_root = data .. '/site'
local cloned_root = packages_root .. '/pack/packages/start'

local flatten_cloned_path = cloned_root .. '/flatten.nvim'
local flatten_url = 'https://github.com/willothy/flatten.nvim.git'

local toggleterm_cloned_path = cloned_root .. '/toggleterm.nvim'
local toggleterm_url = 'https://github.com/akinsho/toggleterm.nvim.git'

vim.fn.mkdir(cloned_root, 'p')
vim.opt.pp:prepend(packages_root)
vim.opt.rtp:prepend(packages_root)

if not vim.loop.fs_stat(flatten_cloned_path) then
  vim.fn.system({ 'git', 'clone', flatten_url, flatten_cloned_path })
end

if not vim.loop.fs_stat(toggleterm_cloned_path) then
  vim.fn.system({ 'git', 'clone', toggleterm_url, toggleterm_cloned_path })
end

local toggleterm = require('toggleterm')
local flatten = require('flatten')

toggleterm.setup()
flatten.setup({
  window = {
    open = 'alternate',
  },
  callbacks = {
    should_block = function(argv)
      return vim.tbl_contains(argv, '-b')
    end,
    post_open = function(bufnr, winnr, ft, is_blocking)
      if not is_blocking then
        vim.api.nvim_set_current_win(winnr)
      end

      if ft == 'gitcommit' or ft == 'gitrebase' then
        vim.api.nvim_create_autocmd('BufWritePost', {
          buffer = bufnr,
          once = true,
          callback = function()
            vim.defer_fn(function()
              vim.api.nvim_buf_delete(bufnr, {})
            end, 50)
          end,
        })
      end
    end,
  },
  block_for = {
    gitcommit = true,
    gitrebase = true,
  },
})

To Reproduce Steps to reproduce the behavior:

  1. Save the config above as minimal.lua
  2. cd to a random git repo with at least two commits
  3. nvim --clean -u minimal.lua
  4. :ToggleTerm
  5. Inside toggleterm, execute command git rebase -i HEAD^^
  6. The git interactive buffer is shown, change the first word in the second line to reword
  7. :w
  8. The git rewording buffer is shown, reword the commit and :w
  9. An empty buffer is shown
  10. :ToggleTerm --> the terminal occupies the both windows (bug)

Expected behavior In step 10, the terminal should just be opened in the lower window not both

Screenshots

https://github.com/willothy/flatten.nvim/assets/76579810/407e575b-d85f-4930-9f56-f54ce0f58963

Desktop (please complete the following information):

Additional context Add any other context about the problem here.

willothy commented 1 year ago

Agreed! I'll look into this ASAP :)

EDIT: Not able to reproduce with my config, but I'll try your minimal config later today.

Bekaboo commented 1 year ago

@willothy Maybe it can be solved by changing the config of flattrn.nvim. I actually don't consider it bug since there's no errors nor warning, just the behavior is a little strange.

willothy commented 1 year ago

@willothy Maybe it can be solved by changing the config of flattrn.nvim. I actually don't consider it bug since there's no errors nor warning, just the behavior is a little strange.

Yeah, likely can be resolved in the config but I'll still take a look. Might be worth adding the solution to the readme in case others experience this.

Bekaboo commented 1 year ago

Not able to reproduce with my config

Mind sharing your config? Is it still the same as the config your shared in the READE? I tried to use that config but get errors when I save the gitrebase file, so I removed all the togglterm.toggle(0) calls -- then the errors are gone but I get the strange behavior in the screen recording.

willothy commented 1 year ago

Not able to reproduce with my config

Mind sharing your config? Is it still the same as the config your shared in the READE? I tried to use that config but get errors when I save the gitrebase file, so I removed all the togglterm.toggle(0) calls -- then the errors are gone but I get the strange behavior in the screen recording.

My config is not the same anymore - here's the link.

I use a custom toggleterm terminal but hopefully it will still work? It may be related to the open setting.

Note that I also have $VISUAL set to nvim -b for blocking.

Let me know if that helps!

Bekaboo commented 1 year ago

@willothy Thanks for sharing your config.

After some small modification it works like a charm -- the terminal now automatically reopens itself after blocking and no more error is thrown. Not sure how it functions exactly but for future references the following is a config that Just Woks:

local ok, toggleterm = pcall(require, 'toggleterm')
if not ok then
  print('flatten: toggleterm not found')
  toggleterm = {
    toggle = function(_) end,
  }
end

require('flatten').setup({
  window = {
    open = 'alternate',
  },
  callbacks = {
    should_block = function(argv)
      for _, arg in ipairs(argv) do
        if (arg:find('.git/rebase-merge', 1, true)) then
          return true
        end
      end
      return false
    end,
    post_open = function(bufnr, winnr, ft, is_blocking)
      if is_blocking or ft == 'gitcommit' or ft == 'gitrebase' then
        -- Hide the terminal while it's blocking
        toggleterm.toggle(0)
      else
        -- If it's a normal file, just switch to its window
        vim.api.nvim_set_current_win(winnr)
      end
      -- If the file is a git commit or git rebase, create one-shot autocmd to
      -- delete its buffer on write
      if ft == 'gitcommit' or ft == 'gitrebase' then
        vim.api.nvim_create_autocmd('BufWritePost', {
          buffer = bufnr,
          once = true,
          callback = function()
            -- This is a bit of a hack, but if you run bufdelete
            -- immediately the shell can occasionally freeze
            vim.defer_fn(function()
              vim.api.nvim_buf_delete(bufnr, {})
            end, 50)
          end,
        })
      end
    end,
    block_end = function()
      -- After blocking ends (for a git commit, etc), reopen the terminal
      vim.defer_fn(function()
        toggleterm.toggle(0)
      end, 50)
    end,
  },
})
willothy commented 1 year ago

Awesome, glad I could help!