nvim-tree / nvim-tree.lua

A file explorer tree for neovim written in lua

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

A git-dirty folder is (inconsistently) highlighted by `NvimTreeGitStaged` instead of `NvimTreeGitDirty`

dasupradyumna opened this issue · comments

Description

Hello, I use nvim-tree with git highlight files enabled and git status icons disabled. Recently, while working on my neovim config, I noticed odd behavior: in some cases, when a folder contains both staged and changed nodes, the folder is highlighted incorrectly as staged, instead of the expected dirty.

Neovim version

NVIM v0.9.0-dev
Build type: RelWithDebInfo
LuaJIT 2.1.0-beta3

Operating system and version

Linux Tensei 5.15.0-67-generic #74~20.04.1-Ubuntu

nvim-tree version

bbb6d48

Minimal config

local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({
    "git",
    "clone",
    "--filter=blob:none",
    "git@github.com:folke/lazy.nvim.git",
    "--branch=stable",
    lazypath,
  })
end
vim.opt.rtp:prepend(lazypath)

require('lazy').setup {
  {
    'nvim-tree/nvim-tree.lua',
    dependencies = { 'nvim-tree/nvim-web-devicons' },

    config = function()
      vim.g.loaded_netrw = 1
      vim.g.loaded_netrwPlugin = 1

      require('nvim-tree').setup {
        git = { ignore = false, show_on_open_dirs = false },
        renderer = {
          highlight_git = true,
          icons = { show = { folder_arrow = false, git = false } },
        },
      }

      -- set highlights
      vim.o.termguicolors = true
      vim.cmd.colorscheme 'koehler'
      vim.cmd.highlight 'Directory guifg=#79c0ff'
      vim.cmd.highlight 'NvimTreeGitStaged guifg=#aff5b4'
      vim.cmd.highlight 'NvimTreeGitDirty guifg=#e3b341'
      vim.cmd.highlight 'NvimTreeGitNew guifg=#56d364'
      vim.cmd.highlight 'NvimTreeGitRenamed guifg=#f0883e'
      vim.cmd.highlight 'NvimTreeGitDeleted guifg=#f85149'
    end,
  }
}

Steps to reproduce

  1. Open NeoVim nvim -nu /tmp/nvt-min.lua
  2. Open nvim-tree :NvimTreeOpen<CR>
  3. Create a folder parent in any testing folder.
  4. Initialize a repository git init inside parent.
  5. Create the below folder structure and run git commit --all -m "init".
  6. Now, add some random text to all the files and stage only a few of them as per the below folder structure.
parent/ (should be dirty, and shown as dirty)
|   one/ (should be dirty, and shown as dirty)
|   |   one_one.txt (dirty)
|   |   one_two.txt (staged)
|   two/ (should be dirty, but shown as staged)
|   |   two_one/ (should be dirty, and shown as dirty)
|   |   |   two_one_one.txt (dirty)
|   |   |   two_one_two.txt (staged)
|   |   two_two.txt (staged)

This is just one particular example, but I have seen this occur in my neovim config repo as well. I was not able to pinpoint a pattern from it; but it is inconsistent.

Expected behavior

Any folder with even a single dirty node (file or folder) should be highlighted by NvimTreeGitDirty.

Actual behavior

Above toy example (minimal config behavior) :

bug_nvimtree_git_toy1 bug_nvimtree_git_toy2 bug_nvimtree_git_toy3 bug_nvimtree_git_toy4 As you can see, the dirty folder two is highlighted as staged.


My neovim config repo (miminal config behavior) :

bug_nvimtree_git_my1 bug_nvimtree_git_my2 bug_nvimtree_git_my3 bug_nvimtree_git_my4 Again, both user and plugins are supposed to be dirty but they are highlighted as staged.


Some more undefined behavior :
When the diffchar.lua file was staged and then made dirty, plugins folder is now shown correctly as dirty.

bug_nvimtree_git_my5 bug_nvimtree_git_my6


Overall, the behavior is very inconsistent and random, there seems to be a problematic edge case with the renderer logic.

  vim.g.loaded_netrw = 1
  vim.g.loaded_netrwPlugin = 1

This is way too late. This must be done at the very start of your init.lua.

netrw is not a plugin, it's a core part of vim and must be stopped immediately otherwise it will be implicitly loaded.

In the parent test repo everything is coloured NvimTreeGitNew.

git --no-optional-locks status --porcelain=v1 --ignored=matching -u

A  one/one_two.txt
A  two/two_one/two_one_txt.txt
A  two/two_two.txt
?? one/one_one.txt
?? two/two_one/two_one_one.txt

That's working as intended, however I may have set up the repo incorrectly.

In another repo, colours are as expected.

Perhaps you might share a repo that I can clone to demonstrate the issue.

Any folder with even a single dirty node (file or folder) should be highlighted by NvimTreeGitDirty.

Turn on icons.git for a little more visibility when investigating this issue. When things are working correctly, staged and dirty icons are shown (in that order) for the folder containing staged and dirty files.

In the parent case, only new is shown, which is expected.

A repo that I can clone and use to replicate this is necessary.

Next steps:

  • confirm git statuses via git logging
  • note git icons shown for each directory / file
  • trace highlighting to ensure that the highlight matches the first git icon

When things are working correctly, staged and dirty icons are shown (in that order) ...

Does that mean staged is given higher priority over dirty?? If that is intended, then maybe my expectations are incorrect.

Nevertheless, I will try out your suggestions (regarding icons.git) and get back to you.

Nevertheless, I will try out your suggestions (regarding icons.git) and get back to you.

Thank you. That's just to help us diagnose.

There is a real problem here that we need to fix.

Does that mean staged is given higher priority over dirty?? If that is intended, then maybe my expectations are incorrect.

In the case of highlighting, yes. I think the status of the first icon is the highlighting that should be applied. I'm not sure that we are doing that correctly here.

Any progress @dasupradyumna ?

Diagnostics are necessary to reproduce and resolve this issue.

Closing due to inactivity and lack of reproducer.

Please comment if you have an issues.