lazy.nvim icon indicating copy to clipboard operation
lazy.nvim copied to clipboard

bug: adding 3 or more specs for the same plugin resets `dir` even though `dev = true`

Open dixslyf opened this issue 1 year ago • 2 comments

Did you check docs and existing issues?

  • [X] I have read all the lazy.nvim docs
  • [X] I have searched the existing issues of lazy.nvim
  • [X] I have searched the existing issues of plugins related to this issue

Neovim version (nvim -v)

0.9.5

Operating system/version

NixOS unstable

Describe the bug

When 3 or more specs are added for the same plugin with dev = true on one of the specs, the plugin's dir is reset to ~/.local/share/nvim/lazy/<plugin> rather than set to under dev.path.

When there are only 1 or 2 specs for the plugin, it works as expected.

Steps To Reproduce

  1. Set dev = true for the first spec for a plugin.
  2. Add a second spec for the plugin.
  3. Start Neovim. There will be an error if the plugin wasn't installed under dev.path — this is expected since dev = true causes lazy.nvim to search for the plugin under dev.path.
  4. Add a third spec for the plugin.
  5. lazy.nvim no longer searches under dev.path, but instead searches ~/.local/share/nvim/lazy. It will clone the plugin into that directory if it's configured to install missing plugins.

Expected Behavior

lazy.nvim should still search for the plugin under dev.path when dev = true is set for one of the specs no matter how many specs are defined for a plugin, rather than ~/.local/share/nvim/lazy.

Repro

-- DO NOT change the paths and don't remove the colorscheme
local root = vim.fn.fnamemodify("./.repro", ":p")

-- set stdpaths to use .repro
for _, name in ipairs({ "config", "data", "state", "cache" }) do
  vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name
end

-- bootstrap lazy
local lazypath = root .. "/plugins/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({ "git", "clone", "--filter=blob:none", "https://github.com/folke/lazy.nvim.git", lazypath, })
end
vim.opt.runtimepath:prepend(lazypath)

-- install plugins
local plugins = {
   { "folke/tokyonight.nvim", dev = true },
   { "folke/tokyonight.nvim", opts = { style = "moon" } },
   -- If you comment out the line below, `lazy.nvim` will search for the plugin under `dev.path` as expected.
   -- However, leaving the line uncommented causes `lazy.nvim` to search under `~/.local/share/nvim/lazy`.
   { "folke/tokyonight.nvim", opts = { dim_inactive = true } },
}
require("lazy").setup(plugins, {
  root = root .. "/plugins",
})

vim.cmd.colorscheme("tokyonight")

dixslyf avatar Feb 15 '24 12:02 dixslyf

Below is a comparison of :lua print(vim.inspect(require('lazy').plugins())) between having 2 specs and having 3 specs, with install { missing = false } to remove some extraneous information from the output. I happened to run the repro under Neovim's config directory, so the repro root ended up there.

2 specs:

{ { "folke/tokyonight.nvim",
    _ = {
      dep = false,
      fid = 2,
      handlers = {},
      installed = true,
      is_local = true,
      loaded = {
        start = "start",
        time = 415561
      },
      super = <1>{ "folke/tokyonight.nvim",
        _ = {
          dep = false,
          dir = "/home/shiba/projects/tokyonight.nvim",
          fid = 1
        },
        dev = true,
        dir = "/home/shiba/projects/tokyonight.nvim",
        name = "tokyonight.nvim",
        url = "https://github.com/folke/tokyonight.nvim.git"
      }
    },
    dir = "/home/shiba/projects/tokyonight.nvim",
    lazy = false,
    name = "tokyonight.nvim",
    opts = {
      style = "moon"
    },
    url = "https://github.com/folke/tokyonight.nvim.git",
    <metatable> = {
      __index = <table 1>
    }
  }, { "folke/lazy.nvim",
    _ = {
      dep = false,
      fid = 3,
      installed = true,
      loaded = {
        source = "init.lua",
        time = 12682959
      }
    },
    config = <function 1>,
    dir = "/home/shiba/.config/nvim/.repro/plugins/lazy.nvim",
    lazy = true,
    name = "lazy.nvim",
    url = "https://github.com/folke/lazy.nvim.git"
  } }

3 specs:

{ { "folke/lazy.nvim",
    _ = {
      dep = false,
      fid = 4,
      installed = true,
      loaded = {
        source = "init.lua",
        time = 8610737
      }
    },
    config = <function 1>,
    dir = "/home/shiba/.config/nvim/.repro/plugins/lazy.nvim",
    lazy = true,
    name = "lazy.nvim",
    url = "https://github.com/folke/lazy.nvim.git"
  }, { "folke/tokyonight.nvim",
    _ = {
      dep = false,
      fid = 3,
      handlers = {},
      installed = false,
      super = <1>{ "folke/tokyonight.nvim",
        _ = {
          dep = false,
          fid = 2,
          super = <2>{ "folke/tokyonight.nvim",
            _ = {
              dep = false,
              dir = "/home/shiba/projects/tokyonight.nvim",
              fid = 1
            },
            dev = true,
            dir = "/home/shiba/projects/tokyonight.nvim",
            name = "tokyonight.nvim",
            url = "https://github.com/folke/tokyonight.nvim.git"
          }
        },
        dir = "/home/shiba/projects/tokyonight.nvim",
        name = "tokyonight.nvim",
        opts = {
          style = "moon"
        },
        url = "https://github.com/folke/tokyonight.nvim.git",
        <metatable> = {
          __index = <table 2>
        }
      }
    },
    dir = "/home/shiba/.config/nvim/.repro/plugins/tokyonight.nvim",
    lazy = false,
    name = "tokyonight.nvim",
    opts = {
      dim_inactive = true
    },
    url = "https://github.com/folke/tokyonight.nvim.git",
    <metatable> = {
      __index = <table 1>
    }
  } }

Looking at the outputs above and lazy.nvim's code, the issue seems to stem from the interaction between plugin._] (src), how plugin.dir is set based on plugin._.dir (src) and how it's also set during merging (src).

dixslyf avatar Feb 15 '24 13:02 dixslyf

Hi @dixslyf,

I can confirm this.

You don't have to set the dev property on the plugin itself. It's possible to add the name of the plugin to config.dev.patterns. This ensures that each individual spec of the plugin has the correct setting.

config = {
  ...
  dev = {
    patterns = { "tokyonight" }
  }
  ...
}

abeldekat avatar Feb 18 '24 19:02 abeldekat