Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Lazy loading #421

Closed
GaetanLepage opened this issue Jun 11, 2023 · 65 comments
Closed

[Feature] Lazy loading #421

GaetanLepage opened this issue Jun 11, 2023 · 65 comments
Assignees
Labels
enhancement New feature or request

Comments

@GaetanLepage
Copy link
Member

GaetanLepage commented Jun 11, 2023

-->Summary: https://notes.glepage.com/rA_fyfKESvC9OxGGNHOYXw#Lazy-Loading <--

Currently, nixvim relies on the neovim built-in way of loading plugins.
This is implemented by nixpkgs neovim's module. It has the advantage of existing and leveraging the collection of plugins packaged in nixpkgs.

With that said, the very popular lazy.nvim plugin manager proposes a more performant way of loading plugins.
Imitating their lazy loading process could be a very valuable addition to nixvim.
I would guess that this feature should be optional so that conventional loading would stay the default.

As of today, no-one has started to work on this issue.
Feel free to go and make a PR, even if the work is in draft-stage. I will personally be glad to review and discuss a proposed implementation.

@pta2002
Copy link
Collaborator

pta2002 commented Jun 11, 2023

A (relatively) easy way to do this, compared to lazy.nvim's approach of basically redoing the whole lazy-loading machinery in neovim, is to make use of optional plugin loading - this is supported, I don't really remember how, but it's a matter of checking how wrapNeovim works.

This way, we can :packadd the packages only when they're needed - AFAIK this is basically how plugin lazy-loading has been done in the past.

Second, probably easier, option - the vast majority of the plugins we support are lua-based plugins. The majority of the loading time there is spent on the setup function. What if we just avoid calling that function until it's needed?

Either way, I will be looking into how lazy-loading in neovim has been traditionally done, since I don't have much experience with it, and will try to come up with some way it could work.

@pta2002
Copy link
Collaborator

pta2002 commented Jun 11, 2023

Also, another feature lazy.nvim supports is bytecode pre-compilation. This is actually totally something we could do! Basically just need to wrap the plugin's derivations to add that. Something to look into, but I'd say this is better off as a separate feature.

@pta2002
Copy link
Collaborator

pta2002 commented Jun 11, 2023

Some references:

  • Examples of lazyloading (Neovim discourse) - Basically, create some convenience functions for delaying lazy-loading, and then bind them that way. We have all the machinery required right now - we can create autocommands, rebind commands and rebind keys. With this, we can just shim a plugin's commands and :packadd the plugin when they're called, or wait for an autocommand to load them.

@GaetanLepage GaetanLepage pinned this issue Jun 15, 2023
@GaetanLepage
Copy link
Member Author

Either way, I will be looking into how lazy-loading in neovim has been traditionally done, since I don't have much experience with it, and will try to come up with some way it could work.

Great ! Thanks and good luck :)
Feel free to open a PR as soon as you have a draft so that I can help and provide feedback :)

@GaetanLepage GaetanLepage added the enhancement New feature or request label Jun 22, 2023
@stasjok
Copy link
Contributor

stasjok commented Jul 23, 2023

Yesterday I found out about nixvim. I'm already using home-manager. I'm not sure I would migrate though. I do some customization for neovim loading to greatly improve startup time and I'm not sure I can insert nixvim in that process. But the project looks interesting. Still I wanted to comment about lazy loading. What I think is most important for startup time are:

  1. Reducing vim.api.nvim_list_runtime_paths(). It's an actual search path where neovim will look for files. More plugins, longer the list. What is even worse in nix ecosystem is that every tree-sitter parser is actually a separate plugin. So when you are installing all parsers, your list_runtime_paths contains hundreds of entries. It's very bad for startup time. Just merging all parsers to a single plugin with symlinkJoin can greatly reduce startup time. But I went even further. I merged all plugins into one plugin pack with buildEnv. So my list_runtime_paths contains only 6 entries (.config/nvim, vim-pack-dir, vim-pack-dir/pack/myNeovimPackages/start/plugin-pack, nvim/runtime, vim-pack-dir/pack/myNeovimPackages/start/plugin-pack/after, .config/nvim/after).
    vim.loader can alleviate a long search path, because it caches directories, so nvim will not search in very directory. But vim.loader is only for lua files. Neovim also scan all directories for plugins, ftplugins, syntax and so on. So reducing list_runtime_paths improves things every time you load a buffer (because of autocommands scanning for ftplugin, syntax, indent).
    Overall reducing vim.api.nvim_list_runtime_paths() gave me the biggest impact. But unfortunately it's not an universal solution, because of file collisions. I'm currently removing help tags in every plugin and generating a new one for the entire pack. Also I'm limiting linked directories with pathsToLink.

  2. Byte-compiling every lua file. With nix we have a build step, so it's better to do a compilation beforehand, and not cache during startup. I compile every lua file: every file in every plugin, every file in my .conf/nvim directory, init.lua, and nvim runtime directory. I have a build hook that does that. As a result I have a fast startup time even on first startup and I don't pollute .cache/nvim with thousands of compiled lua files (with nix every new configuration has different path, so there are a lot of old files there). I don't use vim.loader at all. With both 1 and 2 I have even faster startup time than vim.loader. There is one caveat: lua-language-server can't parse compiled files. As a workaround I save a list of directories with original files in json and load it to lua_ls config.

  3. Reduce a number of required lua files. Usually it means not using heavy functions as callbacks for mappings. I mean do something like callback = function() require("plugin.functions").do_something() end. But you don't need to do it if require("plugin").setup() already pulling all relevant files, you won't improve speed in that case, rather the opposite (every time you use that binding).

  4. I don't do it personally, but it's possible to defer plugin setup on some event (like mapping or command). packadd will increase vim.api.nvim_list_runtime_paths() for my case, so I never use optional plugins.

So even not doing any lazy-loading I have a decent startup time. Without all these optimizations vim.loader greatly improves things. But 1) improves it even further. Maybe some of it can be implemented in nixvim. For example merging treesitter parsers in one plugin (minus 200 to vim.api.nvim_list_runtime_paths()) and byte-compiling init.lua (vim.loader doesn't compile it, because it's enabled after).

@GaetanLepage
Copy link
Member Author

Thank you so much @stasjok for this great insight of your config !
This will surely help once we will tackle the performance issue seriously.

@koalagang
Copy link

I'm not using nixvim either because I need the lazy-loading but I'd like to chip in an idea. If you're willing to outsource some of the code, I'd suggest using lazy.nvim seeing as it's pretty good at lazy-loading + it would reduce the maintenance burden for developing nixvim. Its variety of options and features could come in handy. It even has async execution and automatic caching and bytecode compilation of Lua modules for improved performance. You could provide options to configure it in nix and then translate that to lua like you do with the rest of nixvim. Lazy's dir option could be used to specify the path to the plugin in the nix store. For plugins not available in the nix repos, you could generate packages (see how they do it in the nix repos) or even just let lazy.nvim handle it internally (using git) if you don't mind installing stuff outside of the nix store.

I've written some examples below to illustrate the idea.
The nix file:

{
  plugins.lazy = {
    enable = true;

    # install any plugin available in the nix repos
    nix = {

      # this installs vimPlugins.neorg
      neorg = {
        build = ":Neorg sync-parsers";
        dependencies = [
          # these are all from the nix repos too
          # they load when Neorg loads
          plenary-nvim
          nvim-treesitter
          neorg-telescope = {
            dependencies = [ telescope-nvim ];
            config = ''
              -- this is lua code
              -- it does not get loaded until neorg-telescope is loaded
              vim.wo.foldlevel = 99
            '';
          };
        ];
        cmd = "Neorg";
        ft = "norg";
        keys = "<c-t>n";
        # sometimes we like to keep the config in a different file
        # so source it from elsewhere
        config = import ./neorg.nix;
      };

      nvim-colorizer-lua = {
        cmd = "ColorizerToggle"; # only load colorizer when I use :ColorizerToggle
        config = ''
          -- more lua code
          vim.g.termguicolors = true,
          require("colorizer").setup()
        '';
      };
    };

    # obscure plugin that isn't available in the nix repos
    git."Vonr/align.nvim" = {
        branch = "v2";
        # only load align.nvim when the user presses <leader>a in visual mode
        keys = [
          { "<leader>a"; mode = "v"; };
        ];
        config = ''
          vim.keymap.set(
              'v',
              '<leader>a',
              function()
                  require'align'.align_to_string({
                      preview = true,
                  })
              end,
              { noremap = true, silent = true }
          )
        '';
      };
  };
}

This would install pkgs.vimPlugins.lazy-nvim, pkgs.vimPlugins.neorg, pkgs.vimPlugins.nvim-colorizer-lua, pkgs.vimPlugins.plenary-nvim, pkgs.vimPlugins.nvim-treesitter, pkgs.vimPlugins.neorg-telescope and pkgs.vimPlugins.telescope-nvim.
It would also generate a lua file that looks something like this:

-- add lazy.nvim to the runtime path
vim.opt.rtp:prepend("/nix/store/rjkwbzdmdfp9gfrvi0rch5g5illqwbgf-vimplugin-lazy.nvim-2023-08-26")

require("lazy").setup({
  {
      name = "neorg",
      dir = "/nix/store/iwxg2w4blbphyk7yvf7drqkmf8qfyv4x-vimplugin-neorg-2023-09-15",
      build = ":Neorg sync-parsers",
      dependencies = {
          { name = "plenary.nvim", dir = "/nix/store/4f17ss3v7lv580hmca8pc2q3zn33lqk4-lua5.1-plenary.nvim-2023-09-12" },
          { name = "nvim-treesitter", dir = "/nix/store/vp0lhrdzvknz7rb8pc6ndvv28cgsfy14-vimplugin-nvim-treesitter-2023-09-16" },
          {
              name = "telescope.nvim",
              dir = "/nix/store/1ldgn56d6sgmk42n6dna3b91w3si3sn7-lua5.1-telescope.nvim-2023-09-16",
              dependencies = { name = "neorg-telescope", dir = "/nix/store/rvg763iaqbx3czb52ghrsxhidvqqgwbk-vimplugin-neorg-telescope-2023-08-06" },
              config = function()
                -- this is lua code
                -- it does not get loaded until neorg-telescope is loaded
                vim.wo.foldlevel = 99
              end,
          },
      },
      cmd = "Neorg",
      ft = "norg",
      keys = "<c-t>n",
      config = function()
        require("path.to.neorg.config")
      end,
  },

  {
      name = "nvim-colorizer.lua",
      dir = "/nix/store/03k72h7x4m543z7vrqjwbvqjx6j789qg-vimplugin-nvim-colorizer.lua-2023-02-27",
      cmd = "ColorizerToggle",
      config = function()
        -- more lua code
        vim.g.termguicolors = true,
        require("colorizer").setup()
      end,
  },

  {
    "Vonr/align.nvim",
    branch = "v2",
    keys = {{ "<leader>a", mode = "v" }},
    config = function()
        vim.keymap.set(
            'v',
            '<leader>a',
            function()
                require'align'.align_to_string({
                    preview = true,
                })
            end,
            { noremap = true, silent = true }
        )
    end,
  },
})

Note that you shouldn't try to lazy-load lazy.nvim or the colourscheme. These should be loaded on startup.
As a related sidenote, you can install stuff with lazy.nvim without lazy-loading them by using the lazy = false option. If you choose to load the colourscheme plugin using lazy, it's also good practise to use priority = 1000 to make sure it loads before all other plugins.

Cut me some slack if any of the nix or lua code above has mistakes. I'm pretty new to both languages and have so far not used them for anything besides configuring NixOS/home-manager and Neovim.

@koalagang
Copy link

Oh btw, I came across another project called nixneovim, which seems to have pretty much the same goal as you. I don't believe they do lazy-loading but maybe some of their stuff would interest you, such as their auto-updated plugins repo.

@GaetanLepage
Copy link
Member Author

Thanks for the link @koalagang !
I knew that this project existed (it was forked from nixvim a while ago). However, I wasn't aware that they had their own repo.
We used to have an infrastructure to package plugins ourselves within nixvim but we have removed it at some point.
Indeed, we now prefer the approach of upstreaming all missing plugins to nixpkgs. This makes the user experience a smoother.
The only downside is that the users of the stable branch might not get the new/updated plugins. I am not aware of any backporting of the plugins by nixpkgs maintainers... (@teto am I right here ?).
Anyway, we don't backport our updates to the nixvim stable branch.

@teto
Copy link

teto commented Nov 30, 2023

I am not aware of any backporting of the plugins by nixpkgs maintainers... (@teto am I right here ?).

you are right, no backporting. It's not critical software + we usually dont run the tests (when there are tests !) so backporting would be tricky. Plus the tooling is not great.

auto-updated plugins repo.

I am glad to learn about this, I've wanted to see this (not use it though) so that users can contribute to the nixpkgs plugin updater. Haven't seen much contribution from the usual contributors sadly.

@traxys
Copy link
Member

traxys commented Nov 30, 2023

@teto if you are interested I have a different approach for my plugin management:

@teto
Copy link

teto commented Nov 30, 2023

plugins repo uses their own updater so I better understand why they dont contribute to upstream. Would be interesting to compare the features of both and see if we can merge both approaches.

@traxys > I've seen that approach before. it's LGTM and to some extent, I wish we would leverage nix flake archive in the upstream updates like it's done for treesitter grammars already. Configuring neovim via nix is a bit tedious for most things so I use it only when the trade off is positive (plugins with complex dependencies and that) so I maintain a hybrid config with lazy to install hte other half of my plugins.

@koalagang
Copy link

@GaetanLepage I definitely agree that upstreaming plugins is ideal but surely users should have access to a way of installing plugins that haven't been upstreamed? If one wants a plugin immediately and said plugin is not in the nix repos then what would one do? Of course, you should then ask for this to be added and upstreamed so that all users can benefit but I don't think users should be forced to do this, especially considering that, like you rightfully said, those not on the unstable channel would have to wait for a whole new release to install those plugins. There should be some way of grabbing it straight from a git repo just like traditional vim plugin managers do. I think perhaps pkgs.fetchFromGitHub like how zsh's home-manager module does it could work well, though having to specify the revision and sha256 might be annoying if you regularly update your plugins (which I assume most Neovim users do).

Anyway, this might be diverging slightly from the topic of how Nixvim is going to handle lazy-loading.

@musjj
Copy link

musjj commented Nov 30, 2023

though having to specify the revision and sha256 might be annoying if you regularly update your plugins

If you're okay with having flakes as a requirement, you can use builtins.fetchTree instead. It allows you to fetch repos with only the commit hash.

But I do like the idea of generating lazy.nvim configuration though. Might be worth exploring.

@koalagang
Copy link

koalagang commented Nov 30, 2023

@musjj Haha I just discovered like 15 minutes after posting my comment that this is what flakes do 😅
I have my entire NixOS/home-manager setup inside a flake so no worries about adding that as a dependency for me personally, though perhaps others might be hesitant.

But yeah, again I like the idea of using lazy.nvim. It should possible be to do it with home-manager rather than with nixvim, which I am considering. If, instead of using programs.neovim.plugins, you use programs.neovim.extraLuaConfig then you could pass in a lua config that uses lazy.nvim but inside the dir option use ${pkgs.vimPlugins.yourplugin}.

So for example:

{ pkgs, ... }:

{
  programs.neovim.extraLuaConfig = ''
    -- this is lua code
    vim.opt.rtp:prepend(${pkgs.vimPlugins.lazy-nvim})
    require("lazy").setup({
        {
            name = "nvim-colorizer.lua",
            dir = "${pkgs.nvim-colorizer-lua}",
            cmd = "ColorizerToggle",
            config = function()
                vim.g.termguicolors = true,
                require("colorizer").setup()
            end,
        },
    })
 '';
}

Note that name is optional. It's just nice to have because otherwise the Lazy UI will show /nix/store/03k72h7x4m543z7vrqjwbvqjx6j789qg-vimplugin-nvim-colorizer.lua-2023-02-27 as the plugin's name.

The only difference between this and my suggestion earlier was basically that nixvim could do this but allowing the user to write it directly in nix rather than embedding lua code into a nix file.

P.s. I've never done this nor have I seen it being done. It's just something that, logically, I think would work.

@trueNAHO
Copy link
Contributor

There should be some way of grabbing it straight from a git repo just like traditional vim plugin managers do. I think perhaps pkgs.fetchFromGitHub like how zsh's home-manager module does it could work well, though having to specify the revision and sha256 might be annoying if you regularly update your plugins (which I assume most Neovim users do).

https://github.com/NixOS/nixpkgs/blob/76f642f87ff9b752ec652efc75234cf2fdc446aa/doc/languages-frameworks/vim.section.md?plain=1#L129-L167

@trueNAHO
Copy link
Contributor

If, instead of using programs.neovim.plugins, you use programs.neovim.extraLuaConfig then you could pass in a lua config that uses lazy.nvim but inside the dir option use ${pkgs.vimPlugins.yourplugin}.

P.s. I've never done this nor have I seen it being done. It's just something that, logically, I think would work.

Are plugin versions locked with lazy.nvim like with pure Nix?

@bmanuel
Copy link

bmanuel commented Nov 30, 2023

lazy.nvim has a json lockfile that stores the branch and commit for each dependency that it pulls via git. I'm not sure how it handles local directory dependencies.

@koalagang
Copy link

@trueNAHO

As @bmanuel rightfully said, if pulling via git then it will use its own lockfile implementation (lazy-lock.json). If you're pulling the plugins via nix as I demonstrated above, it will save this to your flake.lock if you're a flakes user. If you're using nix for installing the plugins but but you're not using a flake then there will be no lockfile.

@GaetanLepage
Copy link
Member Author

@koalagang I agree, the goal is not to force the user to upstream packages.
Right now there exists two ways of using plugins in nixvim that are not packages in nixpkgs:

  • Inline buildPluginFromNix in your config to create a package for the missing plugins
  • Use the supported plugins.packer plugin manager to manage your plugins the traditional way (like you would do on another distro)

@trueNAHO
Copy link
Contributor

trueNAHO commented Dec 2, 2023

if pulling via git then it will use its own lockfile implementation (lazy-lock.json). If you're pulling the plugins via nix as I demonstrated above, it will save this to your flake.lock if you're a flakes user. If you're using nix for installing the plugins but but you're not using a flake then there will be no lockfile.

This sounds like we could encapsulate the entire lazy.nvim plugin as a Nixvim module without any reproducibility issues.

@MattSturgeon
Copy link
Member

A lazy.nvim module sounds great, although I still think the original proposal of doing as much as possible in nix (at build time) is the ideal.

That said, perfection is the enemy of good...

@pta2002
Copy link
Collaborator

pta2002 commented Dec 4, 2023

Just popping back in here to add a datapoint for lazy.nvim:

We used to have a module for a popular nvim package manager (packer? I forget...). It's what was used before to install packages outside of Nix, but had some issues.

Either way, I'm not particularly opposed to having lazy.nvim as a module, but IMO that's orthogonal to this issue. We have the opportunity to have this done reproducibly at build time, and IMO we should try to do that.

I don't really see a reason not to have both.

@trueNAHO
Copy link
Contributor

trueNAHO commented Dec 4, 2023

I still think the original proposal of doing as much as possible in nix (at build time) is the ideal.

Indeed! Otherwise, IIRC lazy.nvim downloads and installs unavailable plugins only when launching nvim, which is opposed to Nix' build time. Personally, I prefer a fully reproducible all-inclusive Nix installation over a redeployable Nix installation that partially relies on bootstrapping.

I don't really see a reason not to have both.

We could trigger lazy.nvim's installation command during Nix' build time to ensure plugins are downloaded and installed at build time.

@GaetanLepage
Copy link
Member Author

GaetanLepage commented Mar 26, 2024

Recently we introduced new helpers to create plugin modules (mkVimPlugin / mkNeovimPlugin).
Although it was not the primary intent, they will surely make it easier to draft an implementation of lazy loading.
Indeed, it now gets quite easy to isolate the configuration of each plugin and to add new options to all plugins directly (lazyLoad.enable, lazyLoad.event...).

@pkulak
Copy link

pkulak commented Apr 14, 2024

So... it looks like to use the new lazy module we ("we" being me, someone just using nixvim who doesn't really know what's going on) have to re-do how we setup plugins so they can be loaded with lazy? Is that something I should be doing, or is it going to change soon and we're in kindof an interim state at the moment?

@MattSturgeon
Copy link
Member

MattSturgeon commented Apr 14, 2024

to use the new lazy module we have to re-do how we setup plugins?

Currently, yes.

Is that something I should be doing,

If you want to try out lazy loading now, yes. If you don't like re-doing your config, no.

or is it going to change soon and we're in kindof an interim state at the moment?

The plan is to add a lazy options set to all the plugin modules. When that'll happen is up in the air. Currently nobody has enough time/interest, but hopefully soon someone will.

@Eveeifyeve
Copy link

to use the new lazy module we have to re-do how we setup plugins?

Currently, yes.

Is that something I should be doing,

If you want to try out lazy loading now, yes. If you don't like re-doing your config, no.

or is it going to change soon and we're in kindof an interim state at the moment?

The plan is to add a lazy options set to all the plugin modules. When that'll happen is up in the air. Currently nobody has enough time/interest, but hopefully soon someone will.

I had an idea what if lazy.nvim had an option that affects all plugins to lazy load the option could be programs.lazynvim.loadlazy

@GaetanLepage
Copy link
Member Author

This library could be useful: https://github.com/nvim-neorocks/lz.n

@hbjydev
Copy link
Contributor

hbjydev commented Jun 19, 2024

I had an idea what if lazy.nvim had an option that affects all plugins to lazy load the option could be programs.lazynvim.loadlazy

I was just thinking this actually; if I could just enable it then set lazy loading options based on filetype or something and then just enable plugins.lazy and have all the plugins automatically use lazy.nvim, that'd be awesome.

@Eveeifyeve
Copy link

Eveeifyeve commented Sep 6, 2024

I had an idea what if lazy.nvim had an option that affects all plugins to lazy load the option could be programs.lazynvim.loadlazy

I was just thinking this actually; if I could just enable it then set lazy loading options based on filetype or something and then just enable plugins.lazy and have all the plugins automatically use lazy.nvim, that'd be awesome.

Yeah I agree with this, but what about others like rock.nvim you would have to do a warning or panic when using others.

@koalagang
Copy link

koalagang commented Sep 9, 2024

@GaetanLepage

This library could be useful: https://github.com/nvim-neorocks/lz.n

Just came across this independently and came here to suggest this haha. Do you think maybe you could create a module for this like was done for lazy.nvim and then that would essentially be nixvim's lazy-loading feature complete? The reason lazy.nvim was added was purely for it's lazy-loading ability (or at least that's the only reason I suggested it) so lz.n would essentially do this job but without the added code for managing plugin installation (incl. build, branch, tag, commit and version) that nixvim doesn't need because of its use of nix for fetching plugins.

Btw, as an alternative to creating an independent module for lz.n, you could add enabled, beforeAll, before, after, event, cmd, ft, keys, colorscheme (which you actually already have without lz.n), priority and load options (all from the lz.n plugin spec) to every plugin module and then just use lz.n as the back-end to handle all this lazy-loading. This would probably be a more comfortable way of configuring nixvim.

Unless I'm missing something (which is entirely possible 😅), this should solve the problem of lazy-loading for nixvim.

@traxys
Copy link
Member

traxys commented Sep 9, 2024

We now have support for lz-n (see https://nix-community.github.io/nixvim/plugins/lz-n/index.htm).
There is #1875 to apply this to most plugins, but it seems to have stalled a bit, as this is much more involved than supporting lz-n
We also have #1876 that may be a part of implementing this solution, but the exact method is not yet clear

@HeitorAugustoLN
Copy link
Member

Any progress on this feature?

@GaetanLepage
Copy link
Member Author

GaetanLepage commented Dec 1, 2024

Unfortunately, we have not made a ton of progress on this. Things have been very busy lately.
We managed to get the release ready tonight, so we are good for 6 months now !

Basically, implementing lazy loading will boil down to three steps:

  1. Finalize the huge refactoring of nixvim. This means applying the "new" way of writing plugin modules to the entire code-base. More specifically, we need every plugin to use mk[Neo]vimPlugin.
  2. Agree on the API and features we want to support for lazy loading. Most probably, we will rely on lz-n for the implementation.
  3. Write the relevant code:
    • Add the relevant plugins.*.lazyLoading.* by using the mk[Neo]vimPlugin helpers.
    • Wire-up lz-n to implement the actual lazy loading.
    • When enabled, disable the canonical plugin loading in favor of lazy loading.

This will surely takes some time.
In the meantime, we are always looking for help:

  • Writing modules for requested plugins (look for [PLUGIN REQUEST] issues). It has never been this easy.
  • Address other issues/discussion in general.

Anyway, thank you all for your patience. Lazy loading is the number 1 big feature on our TODO list ;)

@khaneliman
Copy link
Contributor

I did create #2577 as a quick POC on how a simple first step implementation could be done. @MattSturgeon and I talked about it a bit on matrix and figure we could roll out the work in steps. The first PR will be that one with the ability for people to manually manage their lazy loading, then we will work on continuing the implementation of making nixvim ease the configuration.

@HeitorAugustoLN
Copy link
Member

HeitorAugustoLN commented Dec 1, 2024

  1. Finalize the huge refactoring of nixvim. This means applying the "new" way of writing plugin modules to the entire code-base. More specifically, we need every plugin to use mk[Neo]vimPlugin.

I am on vacation as of now, so I think I could help with some PRs to do so.

@Eveeifyeve
Copy link

Eveeifyeve commented Dec 1, 2024

Unfortunately, we have not made a ton of progress on this. Things have been very busy lately. We managed to get the release ready tonight, so we are good for 6 months now !

Basically, implementing lazy loading will boil down to three steps:

  1. Finalize the huge refactoring of nixvim. This means applying the "new" way of writing plugin modules to the entire code-base. More specifically, we need every plugin to use mk[Neo]vimPlugin.

  2. Agree on the API and features we want to support for lazy loading. Most probably, we will rely on lz-n for the implementation.

  3. Write the relevant code:

    • Add the relevant plugins.*.lazyLoading.* by using the mk[Neo]vimPlugin helpers.
    • Wire-up lz-n to implement the actual lazy loading.
    • When enabled, disable the canonical plugin loading in favor of lazy loading.

This will surely takes some time. In the meantime, we are always looking for help:

  • Writing modules for requested plugins (look for [PLUGIN REQUEST] issues). It has never been this easy.
  • Address other issues/discussion in general.

Anyway, thank you all for your patience. Lazy loading is the number 1 big feature on our TODO list ;)

Is there a seperate branch to contribute to? As this will change the codebase and will trigger a big build in nixvim builder which is the nix-community infra.

@GaetanLepage
Copy link
Member Author

Is there a seperate branch to contribute to? As this will change the codebase and will trigger a big build in nixvim builder which is the nix-community infra.

Apart from @khaneliman 's PoC PR, no, there is no branch yet.

@GaetanLepage
Copy link
Member Author

GaetanLepage commented Dec 10, 2024

✅ Lazy loading support (beta) 🦥🚀

After a very long time, we are finally releasing lazy loading support in Nixvim !

  • Configure it for each plugin using plugins.*.lazyLoad.*/colorschemes.lazyLoad.*.
  • Documentation example: aerial/lazyLoad.
  • The current implementation uses the lz.n library under the hood.

⚠️ WARNINGS

  • Note that this feature remains experimental.
    We reserve the right to change the options in the near future.
    -> Do not hesitate to share your feedback or eventual bug reports.
  • Only certain plugins support it1 (check the availability of the plugins.FOO.lazyLoad option).
  • Lazy loading is only available on the master branch of nixvim and will not be backported to the stable branches.

Huge props to Austin for doing the core of the work for this feature (see nix-community/nixvim#2602).
Thanks also to the many participants of nix-community/nixvim#421 for sharing their ideas.

Do not hesitate to join our matrix room to discuss and ask your questions !

Thank you all for your patience and happy hacking 😉

Footnotes

  1. Only plugins configured through lua can be supported for now (i.e. using require('foo').setup() under the hood).
    Then, not all lua plugins have been modernized to use our mkNeovimPlugin backend which brings the lazyLoad.* options.

@GaetanLepage
Copy link
Member Author

Initial implementation done in #2602.
Please open new issues to report bugs or request new features.

@HeitorAugustoLN
Copy link
Member

Awesome work guys!

@trueNAHO
Copy link
Contributor

trueNAHO commented Dec 10, 2024

✅ Lazy loading support (beta) 🦥🚀

[...]

⚠️ WARNINGS

  • Note that this feature remains experimental.
    We reserve the right to change the options in the near future.
    -> Do not hesitate to share your feedback or eventual bug reports.
  • Only certain plugins support it1 (check the availability of the plugins.FOO.lazyLoad option).
  • Lazy loading is only available on the master branch of nixvim and will not be backported to the stable branches.

[...]

Footnotes

  1. Only plugins configured through lua can be supported for now (i.e. using require('foo').setup() under the hood).
    Then, not all lua plugins have been modernized to use our mkNeovimPlugin backend which brings the lazyLoad.* options.

Considering how requested this functionality is, it would be great to open a tracking issue for the following tasks in order to keep interested users up-to-date:

  • All plugins (that can leverage lazy loading) are supported.
  • Lazy loading is no longer "experimental".
  • Lazy loading is the new default behaviour for all supported NixVim plugins.

Please write a message in this thread with a link to the new tracking issue in order for everyone to be notified, allowing them to subscribe to the new thread.

@adrian-gierakowski
Copy link

So excited for this! 🥳

@GaetanLepage
Copy link
Member Author

GaetanLepage commented Dec 11, 2024

Considering how requested this functionality is, it would be great to open a tracking issue for the following tasks in order to keep interested users up-to-date:

Good idea ! Opened #2632.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests