sainnhe / gruvbox-material

Gruvbox with Material Palette
MIT License
1.9k stars 164 forks source link

Fails to link hl groups if better perf is enabled #182

Closed EricDriussi closed 1 year ago

EricDriussi commented 1 year ago

I have done the following steps before reporting this issue:

Operating system/version

Linux 6.2.9-arch1-1

Terminal emulator/version

wezterm 20230712-072601-f4abf8fd

$TERM environment variable

xterm-256color

Tmux version

No response

Feature matrix

==============================================================================
lazy: require("lazy.health").check()

lazy.nvim ~
- OK Git installed
- OK no existing packages found by other package managers
- OK packer_compiled.lua not found

==============================================================================
nvim: require("nvim.health").check()

Configuration ~
- OK no issues found

Runtime ~
- OK $VIMRUNTIME: /usr/share/nvim/runtime

Performance ~
- OK Build type: Release

Remote Plugins ~
- OK Up to date

terminal ~
- key_backspace (kbs) terminfo entry: `key_backspace=\177`
- key_dc (kdch1) terminfo entry: `key_dc=\E[3~`
- $TERM_PROGRAM="WezTerm"
- $COLORTERM="truecolor"

==============================================================================
provider: health#provider#check

Clipboard (optional) ~
- OK Clipboard tool found: xclip

Python 3 provider (optional) ~
- pyenv: Path: /usr/share/pyenv/libexec/pyenv
- pyenv: $PYENV_ROOT is not set. Infer from `pyenv root`.
- pyenv: Root: /home/eric/.pyenv
- `g:python3_host_prog` is not set.  Searching for python3 in the environment.
- WARNING pyenv is not set up optimally.
  - ADVICE:
    - Create a virtualenv specifically for Nvim using pyenv, and set `g:python3_host_prog`.  This will avoid the need to install the pynvim module in each version/virtualenv.
- Executable: /usr/bin/python3
- Python version: 3.11.3
- pynvim version: 0.4.3
- OK Latest pynvim is installed.

Python virtualenv ~
- OK no $VIRTUAL_ENV

Ruby provider (optional) ~
- WARNING `ruby` and `gem` must be in $PATH.
  - ADVICE:
    - Install Ruby and verify that `ruby` and `gem` commands work.

Node.js provider (optional) ~
- Node.js: v20.5.0
- WARNING Missing "neovim" npm (or yarn, pnpm) package.
  - ADVICE:
    - Run in shell: npm install -g neovim
    - Run in shell (if you use yarn): yarn global add neovim
    - Run in shell (if you use pnpm): pnpm install -g neovim
    - You may disable this provider (and warning) by adding `let g:loaded_node_provider = 0` to your init.vim

Perl provider (optional) ~
- WARNING "Neovim::Ext" cpan module is not installed
  - ADVICE:
    - See :help |provider-perl| for more information.
    - You may disable this provider (and warning) by adding `let g:loaded_perl_provider = 0` to your init.vim

==============================================================================
vim.lsp: require("vim.lsp.health").check()

- LSP log level : WARN
- Log path: /home/eric/.local/state/nvim_gruv/lsp.log
- Log size: 0 KB

vim.lsp: Active Clients ~
- No active clients

==============================================================================
vim.treesitter: require("vim.treesitter.health").check()

- Nvim runtime ABI version: 15

Minimal vimrc that can reproduce this bug.

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",
    "--single-branch",
    "https://github.com/folke/lazy.nvim.git",
    lazypath,
  })
end
vim.opt.runtimepath:prepend(lazypath)

require("lazy").setup({
  {
    "nvim-neo-tree/neo-tree.nvim",
    cmd = "Neotree",
    branch = "v3.x",
    dependencies = {
      "nvim-lua/plenary.nvim",
      "nvim-tree/nvim-web-devicons",
      "MunifTanjim/nui.nvim",
    },
    opts = {},
  },
  {
    "sainnhe/gruvbox-material",
    lazy = false,
    priority = 1000,
  },
}, {})

vim.g.gruvbox_material_background = "medium"
vim.g.gruvbox_material_better_performance = 1
vim.cmd([[
    function! s:gruvbox_material_custom() abort
      highlight! link NeoTreeNormal Normal
      highlight! link NeoTreeEndOfBuffer Normal
    endfunction
    augroup GruvboxMaterialCustom
      autocmd!
      autocmd ColorScheme gruvbox-material call s:gruvbox_material_custom()
    augroup END
]])
vim.api.nvim_command("colorscheme gruvbox-material")

Steps to reproduce this bug using minimal vimrc

  1. Launch nvim
  2. Run :Neotree

Expected behavior

Both bg colors are the same image

Actual behavior

bg colors differ (they dont if vim.g.gruvbox_material_better_performance = 0) image

antoineco commented 1 year ago

Thanks for including a clear reproduction 🙏 I'm going to look into this.

antoineco commented 1 year ago

Unrelated question: why do you relink NeoTreeEndOfBuffer and NeoTreeNormal using autocmds? Is there a glitch in the way we support NeoTree? (I'm not a NeoTree user myself so it's useful to get that feedback from actual users.)

sainnhe commented 1 year ago

https://github.com/sainnhe/gruvbox-material/blob/b5f8c6a6c1cda630c53b061b765068a0898d47a3/colors/gruvbox-material.vim#L1613-L1634

The expected behavior is darker background as shown in this piece of code, but you added your custom hi groups which change the background color to the same as normal background.

This bug is caused by the order of loading code in vim. When better performance is disabled, the order of loading code is the following:

  1. Load all the code, including this piece of code. At this time, the background color is set to darker.
  2. Load your custom hi groups. At this time, the background color is set to normal.

But with better performance disabled, this piece of code is place in after/syntax/neo-tree/gruvbox_material.vim that will only be load when open a neo-tree buffer, so the order of loading code is the following:

  1. Load basic highlighting code, without neotree code.
  2. Load your custom hi groups. At this time, the background color is set to normal.
  3. Then you opened a neo-tree buffer, the code in after/syntax/neo-tree/gruvbox_material.vim will be loaded. At this time, the background color is set to darker.

There is not a good solution to this problem yet, but there is a dirty hack. You can place your custom code in BufReadPost event, so your custom code will load after after/syntax/neo-tree/gruvbox_material.vim has been loaded.

EricDriussi commented 1 year ago

Thanks a lot for getting back! Regarding this

Unrelated question: why do you relink NeoTreeEndOfBuffer and NeoTreeNormal using autocmds? Is there a glitch in the way we support NeoTree? (I'm not a NeoTree user myself so it's useful to get that feedback from actual users.)

I just wanted to change NeoTree's bg color and followed the instructions in the docs.

Now with the knowledge gathered from our lord and savior @sainnhe, I looked around in NeoTree's docs and found this handler which fits nicely with what you described above (thanks a lot by the way).

So I gave it a try and it turns out it also does the job! Here's the updated working 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",
    "--single-branch",
    "https://github.com/folke/lazy.nvim.git",
    lazypath,
  })
end
vim.opt.runtimepath:prepend(lazypath)

require("lazy").setup({
  {
    "nvim-neo-tree/neo-tree.nvim",
    cmd = "Neotree",
    branch = "v3.x",
    dependencies = {
      "nvim-lua/plenary.nvim",
      "nvim-tree/nvim-web-devicons",
      "MunifTanjim/nui.nvim",
    },
    opts = {
      event_handlers = {
        {
          event = "after_render",
          handler = function()
            vim.cmd([[
              highlight! link NeoTreeNormal Normal
              highlight! link NeoTreeEndOfBuffer Normal
            ]])
          end,
        },
      },
    },
  },
  {
    "sainnhe/gruvbox-material",
    lazy = false,
    priority = 1000,
  },
}, {})

vim.g.gruvbox_material_background = "medium"
vim.g.gruvbox_material_better_performance = 1
vim.api.nvim_command("colorscheme gruvbox-material")

They also provide other "after-type" events that also work by the way, this is just one of them.

It's a less hacky solution, but NeoTree dependent (I understand that this might happen with a lot of other plugins, so the BufReadPost workaround mentioned above might be a better suit depending on the use case).

In any case, I'm closing the issue since this behavior seems pretty central to how the perf improvement is achieved and there are ways to work around it.

Thanks a lot for the help!