diff --git a/README.md b/README.md index 15852f6..bf39cd3 100644 --- a/README.md +++ b/README.md @@ -152,6 +152,7 @@ The Plugin configuration object accepts the following properties: | `init` | `null` | lua code (as string of path) to call before loading the plugin³ | | `config` | `null` | lua code (as string of path) to call after loading the plugin | | `dependencies` | [] | The plugin dependencies⁴ | +| `lazy` | `false` | should the plugin be loaded lazily | > ² The plugin can be either a nix package or an object with only `name` and > `src` as properties. The latter will be used to create a nix package of your diff --git a/lib/deps.nix b/lib/deps.nix index d62e0bf..621dee1 100644 --- a/lib/deps.nix +++ b/lib/deps.nix @@ -97,6 +97,7 @@ then plugin.pname else plugin.name; hasDeps = plugin ? dependencies && plugin.dependencies != []; + isLazy = plugin ? lazy && plugin.lazy; name = pluginName plugin.plugin; in memo @@ -107,6 +108,9 @@ // (mkTypeFn "config") // (optionalAttrs hasDeps { dependencies = map pluginName plugin.dependencies; + }) + // (optionalAttrs isLazy { + lazy = true; }); }; pluginsLuaDef = plugins: lua.nix2lua (foldl' pluginLuaDef {} plugins); diff --git a/lib/mkNeovimPkg.nix b/lib/mkNeovimPkg.nix index 4cdc86e..0b5f14e 100644 --- a/lib/mkNeovimPkg.nix +++ b/lib/mkNeovimPkg.nix @@ -22,7 +22,11 @@ runtimePlugin.plugin = deps.mkRuntimePlugin runtime; plugins = deps.normalizePlugins (dependencies ++ [runtimePlugin sloth-flake]); - extractPlugin = map (p: p.plugin); + extractPlugin = p: { + inherit (p) plugin; + optional = p ? lazy && p.lazy; + }; + extractPlugins = map extractPlugin; customRC = let rc = ({init ? ../lua/default_init.lua, ...}: init) runtime; @@ -32,7 +36,7 @@ neovimConfig = pkgs.neovimUtils.makeNeovimConfig { inherit customRC; - plugins = extractPlugin plugins; + plugins = extractPlugins plugins; } // {luaRcContent = customRC;}; pkg = pkgs.wrapNeovimUnstable package (removeAttrs neovimConfig ["manifestRc" "neovimRcContent"]); diff --git a/lib/types.nix b/lib/types.nix index 1e25622..e80a032 100644 --- a/lib/types.nix +++ b/lib/types.nix @@ -45,7 +45,7 @@ dependencies = option (list drv); # Should this plugin be load lazily ? - # lazy = option bool; + lazy = option bool; # List of events on which the plugin should be loaded # events = option stringList; diff --git a/lua/sloth-flake/init.lua b/lua/sloth-flake/init.lua index cc1961e..f41ad13 100644 --- a/lua/sloth-flake/init.lua +++ b/lua/sloth-flake/init.lua @@ -1,6 +1,10 @@ local deps = require 'sloth-flake.deps' local priv = { - is_loaded = {} + is = { + init = {}, + import = {}, + config = {}, + }, } local M = {} @@ -9,72 +13,86 @@ function M.get(name) return deps[name] end -function M.init_all() - for k, v in pairs(deps) do - M.init(k) +function M.init_non_lazy() + for _, dep in ipairs(M.non_lazy_deps()) do + M.init(dep.name) end end -function M.config_all() - for k, v in pairs(deps) do - M.config(k) +function M.import_non_lazy() + for _, dep in ipairs(M.non_lazy_deps()) do + M.import(dep.name) end end -function M.init(name) - local dep = M.get(name) - if name == nil then - -- TODO Report error ? - elseif dep.init ~= nil then - dep.init() +function M.config_non_lazy() + for _, dep in ipairs(M.non_lazy_deps()) do + M.config(dep.name) end end +function load_fn(type) + return function(name) + local dep = M.get(name) + if priv.is[type][name] then + return + end + priv.is[type][name] = true + if dep[type] ~= nil then + dep[type]() + end + end +end + +M.init = load_fn('init') +M.config = load_fn('config') + +function M.import(name) + if M.is_imported(name) then + return + end + local plugin = M.get(name) + priv.is.import[name] = true + if plugin.lazy then + vim.cmd("packadd " .. name) + end +end + +function M.is_imported(name) + return priv.is.import[name] or false +end + function M.load(name) - if name == nil then - -- TODO Report error ? - elseif M.is_loaded(name) then - -- TODO Nothing todo - else - -- TODO Laod dynamic plugin - priv.is_loaded[name] = true - end + M.init(name) + M.import(name) + M.config(name) end -function M.config(name) - local dep = M.get(name) - if name == nil then - -- TODO Report error ? - elseif dep.config ~= nil then - dep.config() - end +function M.dep_names() + return M.dep_names_by(function() return true end):totable() end -function M.get_dep_names() - local ret = {} - for k, v in pairs(deps) do - ret[#ret + 1] = v.name - end - return ret +function M.dep_names_by(fn) + return M.deps_iter_by(fn):map(function(v) return v.name end) end -function M.load_all() - for k, _v in pairs(deps) do - M.load(k) - end +function M.deps_iter_by(fn) + return vim.iter(deps):map(function(k, v) return v end):filter(fn) end -function M.is_loaded(name) - return priv.is_loaded[name] or false +function M.non_lazy_deps() + return M.deps_iter_by(function(dep) + return not dep.lazy + end):totable() end function M.setup(config) local post_init = config and config.post_init or function() end - M.init_all() + M.init_non_lazy() post_init() - M.load_all() - M.config_all() + M.import_non_lazy() + M.config_non_lazy() end return M