NeogitOrg / neogit

An interactive and powerful Git interface for Neovim, inspired by Magit
MIT License
3.71k stars 221 forks source link

Can't open multiple Neogit tabs in a window #1260

Open EarthyOrange opened 3 months ago

EarthyOrange commented 3 months ago

Description

I want to open multiple Neogit tabs (https://neovim.io/doc/user/tabpage.html) in 1 Neovim window but every time I run the command :tab Neogit cwd=<git dir>, the new git directory is opened in the current tab. Therefore, I can run only 1 instance of Neogit in 1 window.

Neovim version

NVIM v0.9.4 Build type: Release LuaJIT 2.1.0-beta3

Operating system and version

macOS 13.6.4

Steps to reproduce

  1. On terminal run nvim
  2. On nvim run :Neogit cwd=<git-dir-1>
  3. On nvim run :tab Neogit cwd=<git-dir-2>

Expected behavior

There should be 2 Neogit tabs pointing to respective git directories.

Actual behavior

On nvim run :Neogit cwd=<git-dir-1>:

  1. The current tab shows Neogit instance pointing to git-dir-1

On nvim run :tab Neogit cwd=<git-dir-2>:

  1. A new blank second tab is opened
  2. The first tab now points to git-dir-2
  3. No tab points to git-dir-1

Minimal config

-- NOTE: See the end of this file if you are reporting an issue, etc. Ignore all the "scary" functions up top, those are
-- used for setup and other operations.
local M = {}

local base_root_path = vim.fn.fnamemodify(debug.getinfo(1, "S").source:sub(2), ":p:h") .. "/.min"
function M.root(path)
  return base_root_path .. "/" .. (path or "")
end

function M.load_plugin(plugin_name, plugin_url)
  local package_root = M.root("plugins/")
  local install_destination = package_root .. plugin_name
  vim.opt.runtimepath:append(install_destination)

  if not vim.loop.fs_stat(package_root) then
    vim.fn.mkdir(package_root, "p")
  end

  if not vim.loop.fs_stat(install_destination) then
    print(string.format("> Downloading plugin '%s' to '%s'", plugin_name, install_destination))
    vim.fn.system({
      "git",
      "clone",
      "--depth=1",
      plugin_url,
      install_destination,
    })
    if vim.v.shell_error > 0 then
      error(string.format("> Failed to clone plugin: '%s' in '%s'!", plugin_name, install_destination),
        vim.log.levels.ERROR)
    end
  end
end

---@alias PluginName string The plugin name, will be used as part of the git clone destination
---@alias PluginUrl string The git url at which a plugin is located, can be a path. See https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols for details
---@alias MinPlugins table<PluginName, PluginUrl>

---Do the initial setup. Downloads plugins, ensures the minimal init does not pollute the filesystem by keeping
---everything self contained to the CWD of the minimal init file. Run prior to running tests, reproducing issues, etc.
---@param plugins? table<PluginName, PluginUrl>
function M.setup(plugins)
  vim.opt.packpath = {}                      -- Empty the package path so we use only the plugins specified
  vim.opt.runtimepath:append(M.root(".min")) -- Ensure the runtime detects the root min dir

  -- Install required plugins
  if plugins ~= nil then
    for plugin_name, plugin_url in pairs(plugins) do
      M.load_plugin(plugin_name, plugin_url)
    end
  end

  vim.env.XDG_CONFIG_HOME = M.root("xdg/config")
  vim.env.XDG_DATA_HOME = M.root("xdg/data")
  vim.env.XDG_STATE_HOME = M.root("xdg/state")
  vim.env.XDG_CACHE_HOME = M.root("xdg/cache")

  -- NOTE: Cleanup the xdg cache on exit so new runs of the minimal init doesn't share any previous state, e.g. shada
  vim.api.nvim_create_autocmd("VimLeave", {
    callback = function()
      vim.fn.system({
        "rm",
        "-r",
        "-f",
        M.root("xdg")
      })
    end
  })
end

-- NOTE: If you have additional plugins you need to install to reproduce your issue, include them in the plugins
-- table within the setup call below.
M.setup({
  plenary = "https://github.com/nvim-lua/plenary.nvim.git",
  telescope = "https://github.com/nvim-telescope/telescope.nvim",
  diffview = "https://github.com/sindrets/diffview.nvim",
  neogit = "https://github.com/NeogitOrg/neogit"
})
-- WARN: Do all plugin setup, test runs, reproductions, etc. AFTER calling setup with a list of plugins!
-- Basically, do all that stuff AFTER this line.
require("neogit").setup({}) -- For instance, setup Neogit
CKolkey commented 3 months ago

Not a bug - that's how it works on master. However, I've improved the experience a lot on the nightly branch, which will be released with nvim 0.10. Better CWD handling, that sort of thing. Try it out :)

asmodeus812 commented 3 months ago

@CKolkey did try that myself, i have kind=tab, seems like if you already have an opened neogit status in a tab, if you call Neogit cwd=... again the neogit tab is not focused (but if you manually go to the tab it seems the state is updated). Tried on nightly with .setup() call.

Is there a way allowing us to have multiple tabs opened for git status each for unique cwd ? I have a similar use case as the OP, where i might have multiple files from multiple working directories opened in the current nvim window. So instead of updaing the current neogit tab status if it exists, it will open a new tab for the cwd, if a tab for that cwd exists, then it can be focused and updated (working similarly to what is intended atm) - could be an opt in. Not sure how it would work with kind=split, but this could be only applicable for kind=tab wdyt ?

CKolkey commented 2 months ago

It's going to require a bit of doing.. I use vim.uv.getcwd() all over to find the correct status buffer instance and repository object. I'm beginning to think that relying on that was a mistake in the first place as it's effectively a global variable. It's no issue to run git against a specific directory with the -C flag, but what I need to do is start passing the CWD into pretty much every constructor function, so it can either be consumed (run a git command) or passed on to a buffer that would consume it.

Not a huge change, I think, but a bit tedious. However, it would mean that tabs/splits/whatever could point to a project directory and all coexist. I'd happily accept a PR if anyone wants to tackle this, otherwise I'll probably get to it at some point, but I couldn't say when.