Skip to content

Neogit's foldminlines=0 affects other buffers #1521

@igorlfs

Description

@igorlfs

Description

Hello!

Once more, opening an issue with folds 😅

This one really hinders the experience with Treesitter folds and, at first, I thought it was an issue on neovim's side. But on further inspection, Neogit seems to be the culprit. Whenever I use :Neogit and I switch to a file that contains git changes, treesitter's folds are randomly modified (mainly around the changed region). It's easier to notice when the foldcolumn is enabled, for instance:

Sample file, where lines 11 and 12 were added but not yet commited
return {
  "catppuccin/nvim",
  name = "catppuccin",
  priority = 1000,
  opts = {
      term_colors = true,
      highlight_overrides = {
          mocha = function(mocha)
              return {
                  FloatBorder = { fg = mocha.blue, bg = mocha.mantle },

                  Comment = { fg = mocha.overlay1 },
              }
          end,
      },
      integrations = {
          mason = true,
          noice = true,
          octo = true,
          diffview = true,
          telescope = {
              style = "nvchad",
          },
      },
  },
}
Before After
image image

Looking at other issues, it looks like there's a workaround for this situation when using the nvim-ufo plugin. Could a similar solution be built for the built-in Treesitter foldexpr?

Neovim version

NVIM v0.11.0-dev-983+g80e37aa533
Build type: Release
LuaJIT 2.1.1727870382

Operating system and version

Arch Linux 6.11.4

Steps to reproduce

  1. nvim -nu minimal.lua
  2. Open a modified file
  3. :Neogit
  4. Switch back to file

Expected behavior

No response

Actual behavior

Shown in the description.

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

vim.api.nvim_create_autocmd("FileType", {
	pattern = { "lua" }, -- could be any filetype
	callback = function()
		vim.treesitter.start()
		vim.wo.foldexpr = "v:lua.vim.treesitter.foldexpr()"
		vim.wo.foldmethod = "expr"
		vim.wo.foldcolumn = "1" -- makes the issue more noticeable
		vim.wo.number = true
	end,
})

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions