nvf icon indicating copy to clipboard operation
nvf copied to clipboard

Lazy.nvim as a module to allow lazy plugin loading

Open Petingoso opened this issue 1 year ago • 9 comments

⚠️ Please verify that this feature request has NOT been suggested before.

  • [X] I checked and didn't find a similar feature request

🏷️ Feature Type

API Additions

🔖 Feature description

Lazy loading is a very nice feature, but implementing it from scratch might be a lot of work. As such I propose easy access to lazy for allowing it to manage plugins.

✔️ Solution

Some sort of API. It would take nix expressions

lazy = {
    plugin y = {
    link = ...
    setup = ...
    lazy = ...
};
}

This would then be passed along in lua to lazy (As lazy is very integrated with lua)

❓ Alternatives

There's the option of implementing lazy plugin management, but that would require a lot of overhead in plugin loading

📝 Additional Context

No response

Petingoso avatar Feb 08 '24 21:02 Petingoso

To be fair, I'm not very keen on plugin managers. Never been, never will.

On another hand, lazy's ability to load plugins lazily (and the fact that it's the de-facto plugin manager of most configurations right now) inclines me to add support for it even though I will not use (nor actively support it). Problem though, is that the config schema is really complicated, and perhaps too complicated to even attempt generating from Nix.

The readme example looks as follows:

return {
  -- the colorscheme should be available when starting Neovim
  {
    "folke/tokyonight.nvim",
    lazy = false, -- make sure we load this during startup if it is your main colorscheme
    priority = 1000, -- make sure to load this before all the other start plugins
    config = function()
      -- load the colorscheme here
      vim.cmd([[colorscheme tokyonight]])
    end,
  },

  -- I have a separate config.mappings file where I require which-key.
  -- With lazy the plugin will be automatically loaded when it is required somewhere
  { "folke/which-key.nvim", lazy = true },

  {
    "nvim-neorg/neorg",
    -- lazy-load on filetype
    ft = "norg",
    -- options for neorg. This will automatically call `require("neorg").setup(opts)`
    opts = {
      load = {
        ["core.defaults"] = {},
      },
    },
  },

  {
    "dstein64/vim-startuptime",
    -- lazy-load on a command
    cmd = "StartupTime",
    -- init is called during startup. Configuration for vim plugins typically should be set in an init function
    init = function()
      vim.g.startuptime_tries = 10
    end,
  },

  {
    "hrsh7th/nvim-cmp",
    -- load cmp on InsertEnter
    event = "InsertEnter",
    -- these dependencies will only be loaded when cmp loads
    -- dependencies are always lazy-loaded unless specified otherwise
    dependencies = {
      "hrsh7th/cmp-nvim-lsp",
      "hrsh7th/cmp-buffer",
    },
    config = function()
      -- ...
    end,
  },

  -- if some code requires a module from an unloaded plugin, it will be automatically loaded.
  -- So for api plugins like devicons, we can always set lazy=true
  { "nvim-tree/nvim-web-devicons", lazy = true },

  -- you can use the VeryLazy event for things that can
  -- load later and are not important for the initial UI
  { "stevearc/dressing.nvim", event = "VeryLazy" },

  {
    "Wansmer/treesj",
    keys = {
      { "J", "<cmd>TSJToggle<cr>", desc = "Join Toggle" },
    },
    opts = { use_default_keymaps = false, max_join_length = 150 },
  },

  {
    "monaqa/dial.nvim",
    -- lazy-load on keys
    -- mode is `n` by default. For more advanced options, check the section on key mappings
    keys = { "<C-a>", { "<C-x>", mode = "n" } },
  },

  -- local plugins need to be explicitly configured with dir
  { dir = "~/projects/secret.nvim" },

  -- you can use a custom url to fetch a plugin
  { url = "[email protected]:folke/noice.nvim.git" },

  -- local plugins can also be configure with the dev option.
  -- This will use {config.dev.path}/noice.nvim/ instead of fetching it from Github
  -- With the dev option, you can easily switch between the local and installed version of a plugin
  { "folke/noice.nvim", dev = true },
}

While we can try and generate the top-level attributes (e.g. lazy, priority, ft), config and keys tables look quite difficult to deal with.

I'll go ahead and CC @horriblename to see what he thinks about the implementation as he's looking at a plugin config schema generated from Nix.

NotAShelf avatar Feb 08 '24 21:02 NotAShelf

Indeed that tables might be difficult to parse. There's the possibly of just using the deprecating the keys option and instead handling something like

#check if lazy.plugin is enabled/installed
if lazy.plugins.PluginX.enabled = true {
    vim.maps.... = {
    action = "Plugin Command"
    }
};

The config part is a literal lua function isn't it? Couldn't it be passed literally?

Petingoso avatar Feb 08 '24 21:02 Petingoso

Indeed that tables might be difficult to parse. There's the possibly of just using the deprecating the keys option and instead handling something like

#check if lazy.plugin is enabled/installed
if lazy.plugins.PluginX.enabled = true {
    vim.maps.... = {
    action = "Plugin Command"
    }
};

I am really not looking to replace the plugin management with lazy - which is why I would not want to deprecate vim.keys

The config part is a literal lua function isn't it? Couldn't it be passed literally?

It could, but at that point why use a module? We have two lua-first APIs that you can use to configure a plugin

NotAShelf avatar Feb 08 '24 21:02 NotAShelf

I am really not looking to replace the plugin management with lazy - which is why I would not want to deprecate vim.keys

Oh I might have not made myself clear or used the wrong key function. I meant creating custom bindings or prompting the user to, instead of parsing the lazy "keys" field

It could, but at that point why use a module? We have two lua-first APIs that you can use to configure a plugin

That's true, and excuse me my lack of knowledge on this, but using these APIs wouldn't the plugins be "required" and as such loaded automatically? Or is that only when requiring manually somewhere?

Petingoso avatar Feb 08 '24 21:02 Petingoso

That's true, and excuse me my lack of knowledge on this, but using these APIs wouldn't the plugins be "required" and as such loaded automatically? Or is that only when requiring manually somewhere?

If you use the extra plugin API, you would be loading the plugin and providing its configuration at the same time. If, instead, using the extra Lua config API, you can have your plugins and Lazy.nvim in your optionalPlugins (added to path but not loaded) then you can provide raw Lua configuration (for either the plugins or lazy.nvim directly) to completely control their behaviour.

NotAShelf avatar Feb 09 '24 07:02 NotAShelf

for what it's worth, the extraPlugins API should be fairly easy to add lazy.nvim support.

The main problem is with converting builtin plugins: we might need to go all in and make lazy.nvim mandatory for everyone, I'm not sure if it's a good idea + its a lot work

lazy loading is something we've been missing but unfortunately there's no easy way out

horriblename avatar Feb 09 '24 17:02 horriblename

for what it's worth, the extraPlugins API should be fairly easy to add lazy.nvim support.

how do we want to approach this though, change the extraPlugin API to properly support lazy.nvim or duplicate it in a mutually exclusive module to use lazy.nvim instead?

The main problem is with converting builtin plugins:

can lazy.nvim not coexist with native plugin loading?

NotAShelf avatar Feb 12 '24 07:02 NotAShelf

mutually excluisve module sounds easier to migrate for the user.

can lazy.nvim not coexist with native plugin loading?

yes it can, I was thinking that perhaps adding lazy.nvim support would mean rewriting most of the lua code and maintaining two versions of the config, but on second thought, that's probably unnecessary.

horriblename avatar Feb 12 '24 10:02 horriblename

Then I think we can look at implementing an alternative plugin system that utilizes lazy.nvim for those who prefer to use it. Though, I'd first like to finalize the nix -> lua libraries and finish #181.

NotAShelf avatar Feb 15 '24 06:02 NotAShelf