folke / lazy.nvim

💤 A modern plugin manager for Neovim
https://lazy.folke.io/
Apache License 2.0
14.6k stars 353 forks source link

bug: plugins not loaded due to cond are not contained in the lazy-lock.json file #1015

Closed Mephistophiles closed 1 year ago

Mephistophiles commented 1 year ago

Did you check docs and existing issues?

Neovim version (nvim -v)

v0.9.1

Operating system/version

Linux

Describe the bug

If a plugin is disabled via cond, in my case it is:

return {
    'goolord/alpha-nvim',
    cond = function()
        -- don't start when opening a file
        if vim.fn.argc() > 0 then
            return false
        end

        -- skip stdin
        if vim.fn.line2byte '$' ~= -1 then
            return false
        end

        -- Handle nvim -M
        if not vim.o.modifiable then
            return false
        end

        for _, arg in pairs(vim.v.argv) do
            -- whitelisted arguments
            -- always open
            if arg == '--startuptime' then
                return true
            end

            -- blacklisted arguments
            -- always skip
            if
                arg == '-b'
                -- commands, typically used for scripting
                or arg == '-c'
                or vim.startswith(arg, '+')
                or arg == '-S'
            then
                return false
            end
        end

        return true
    end,
    dependencies = { 'nvim-tree/nvim-web-devicons' },
    config = function()
        require('alpha').setup(require('alpha.themes.startify').config)
    end,
}

then the plugin will not be shown in the lazy-lock.json file.

Steps To Reproduce

  1. Add plugin with cond
  2. Open nvim when cond is false
  3. Run Lazy sync
  4. Check the lazy-lock.json

Expected Behavior

Described plugin in the lazy-lock.json

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",
    {
        "goolord/alpha-nvim",
        cond = function()
            -- don't start when opening a file
            if vim.fn.argc() > 0 then
                return false
            end

            -- skip stdin
            if vim.fn.line2byte("$") ~= -1 then
                return false
            end

            -- Handle nvim -M
            if not vim.o.modifiable then
                return false
            end

            for _, arg in pairs(vim.v.argv) do
                -- whitelisted arguments
                -- always open
                if arg == "--startuptime" then
                    return true
                end

                -- blacklisted arguments
                -- always skip
                if
                    arg == "-b"
                    -- commands, typically used for scripting
                    or arg == "-c"
                    or vim.startswith(arg, "+")
                    or arg == "-S"
                then
                    return false
                end
            end

            return true
        end,
        dependencies = { "nvim-tree/nvim-web-devicons" },
        config = function()
            require("alpha").setup(require("alpha.themes.startify").config)
        end,
    },
}
require("lazy").setup(plugins, {
    root = root .. "/plugins",
})

vim.cmd.colorscheme("tokyonight")
-- add anything else here
valeth commented 1 year ago

I think the issue is caused by enabled being set in Spec:fix_cond in plugin.lua.

Commenting that line out locally made it so that the plugin is included in the lock file again, but still prevented loading like expected.

abeldekat commented 1 year ago

Hello @Mephistophiles,

I thought about this issue, and would like to share a non-authoritative opinion.

The cond keyword indeed either disables or enables the plugin in the current vim session.

It differs from the enabled keyword in two ways:

Quoting the description of cond from the specs:

When false, or if the function returns false, then this plugin will not be loaded. Useful to disable some plugins in vscode, or firenvim for example.

An example for vscode can be found here. Note that the checker and change_detection are disabled.

An unofficial example for firenvim can be found in this discussion. Also, important info can be found in this pull request.

Now, both vscode and firenvim are external environments. In my opinion, the maintenance of plugins(affecting the contents of lazy-lock.json), is not expected to be done inside those environments.

Thus, I think that the cond keyword is not the best approach to accomplish the behaviour you are looking for.

As an alternative, the plugin could be loaded only on an event. The value of the event property can be a function. Your use case can be implemented by conditionally returning an empty table.

Example:

  {
    "goolord/alpha-nvim",
    event = function()
      local should_load = function()
        -- don't start when opening a file
        if vim.fn.argc() > 0 then
          return false
        end

        -- more logic here

        return true
      end

      if should_load() then
        return { "VimEnter" }
      else
        return {}
      end
    end,
    dependencies = { 'nvim-tree/nvim-web-devicons' },
    config = function()
        require('alpha').setup(require('alpha.themes.startify').config)
    end,
  }

Best regards!

Mephistophiles commented 1 year ago

Hi @abeldekat !

Thanks for the answer! I'll try to do as you suggested. Another small question: how to properly filter by filetype AND event? eventName *.filetype? or is there a more convenient variant?

abeldekat commented 1 year ago

@Mephistophiles,

You're welcome!

Regarding your question, as an example, this could work:

return {
  {
    "linux-cultist/venv-selector.nvim",
    event = "BufReadPost *.py",
    opts = {},
  },
}

I don't think that will work for the events lazy.nvim provides. See also this discussion.