From b60e6a3934fe60f42ebcf31d8b9f8297677dd197 Mon Sep 17 00:00:00 2001 From: Squibid Date: Sun, 29 Jun 2025 18:12:30 -0400 Subject: [PATCH] allow lazy loading colorschemes --- lua/dep.lua | 2 + lua/dep/lazy/init.lua | 37 ++++++++++++ lua/dep/lazy/{utils.lua => loader/init.lua} | 41 +++++++------- lua/dep/lazy/loader/short.lua | 62 +++++++++++++++++++++ lua/dep/lazy/short.lua | 43 -------------- lua/dep/package.lua | 14 +++-- lua/dep/spec.lua | 7 ++- 7 files changed, 135 insertions(+), 71 deletions(-) create mode 100644 lua/dep/lazy/init.lua rename lua/dep/lazy/{utils.lua => loader/init.lua} (81%) create mode 100644 lua/dep/lazy/loader/short.lua delete mode 100644 lua/dep/lazy/short.lua diff --git a/lua/dep.lua b/lua/dep.lua index 162aef0..da9174a 100644 --- a/lua/dep.lua +++ b/lua/dep.lua @@ -5,6 +5,7 @@ local packager = require('dep.package') local h = require('dep.helpers') local modules = require("dep.modules") local bench = require("dep.bench") +local lazy = require("dep.lazy") -- all functions for convenience local M = {} @@ -62,6 +63,7 @@ return function(opts) M.config_path = debug.getinfo(2, "S").source:sub(2) logger.pipe = logger:setup() bench:setup() + lazy.setup() --- make comparison for table.sort ---@param a package package spec a diff --git a/lua/dep/lazy/init.lua b/lua/dep/lazy/init.lua new file mode 100644 index 0000000..3ca604e --- /dev/null +++ b/lua/dep/lazy/init.lua @@ -0,0 +1,37 @@ +local h = require("dep.helpers") +local packager = require("dep.package") + +---@class lazy +local lazy = {} + +-- since this is already a ridiculous "optimization" we should really be caching +-- the results of this for when the user keeps on loading the colorscheme that +-- they've lazy loaded, that way we speed up the lazy loading process +local function colorscheme() + -- if a colorscheme doesn't exist attempt load it prior to it being set + vim.api.nvim_create_autocmd("ColorschemePre", { + pattern = vim.fn.getcompletion("", "color"), + callback = function(e) + for _, p in pairs(packager.get_packages()) do + if not p.loaded then + for _, ext in ipairs({ ".lua", ".vim" }) do + local path = p.dir.."/colors/"..e.match..ext + if h.uv.fs_stat(path) then + p:ensureadded(true) + -- break out of here, we've loaded the colorscheme + return + end + end + end + end + end + }) +end + +--- setup all lazy handlers +function lazy.setup() + -- start the colorscheme watcher + colorscheme() +end + +return lazy diff --git a/lua/dep/lazy/utils.lua b/lua/dep/lazy/loader/init.lua similarity index 81% rename from lua/dep/lazy/utils.lua rename to lua/dep/lazy/loader/init.lua index 889c9be..7569b9b 100644 --- a/lua/dep/lazy/utils.lua +++ b/lua/dep/lazy/loader/init.lua @@ -1,15 +1,15 @@ local logger = require('dep.log') ----@class lazy +---@class lazy_loader ---@field load function the function to load the plugin ---@field command_ids table the commands that have been registered ---@field auto_ids table the auto commands that have been registered ---@field keybind_ids table the keybinds that have been registered -local lazy = {} +local lazy_loader = {} --- create a new instance of lazy ---@return lazy -function lazy:new() +function lazy_loader:new() local o = {} setmetatable(o, self) @@ -22,22 +22,16 @@ function lazy:new() return o end ---- set the loading function ----@param load function the loading function -function lazy:set_load(load) +--- set the loading callback +---@param load function the loader function +function lazy_loader:set_load(load) self.load = load end ---- get the configured load function ----@return function load function -function lazy:get_load() - return self.load -end - --- create a usercommand which will trigger the plugin to load ---@param name string the name of the command ---@param opts vim.api.keyset.user_command? options -function lazy:cmd(name, opts) +function lazy_loader:cmd(name, opts) opts = opts or {} vim.api.nvim_create_user_command(name, opts['callback'] or function() self:cleanup() @@ -49,7 +43,7 @@ end --- create an auto command which will trigger the plugin to load ---@param event string the event to trigger on ---@param opts vim.api.keyset.create_autocmd? options -function lazy:auto(event, opts) +function lazy_loader:auto(event, opts) opts = opts or {} opts['callback'] = opts['callback'] or function() @@ -62,17 +56,20 @@ end --- create an auto command which will trigger on filetype ---@param filetype string filetype to register the auto on -function lazy:ft(filetype) - lazy:auto("FileType", { +function lazy_loader:ft(filetype) + lazy_loader:auto("FileType", { pattern = filetype }) end +---@class lazy.Opts: vim.keymap.set.Opts +---@field rerun boolean|function weather to rerun and what to do + --- create a keybind which will trigger the plugin to load ---@param mode string the mode to trigger in ---@param bind string the binding to use ----@param opts vim.keymap.set.Opts? options -function lazy:keymap(mode, bind, opts) +---@param opts lazy.Opts? options +function lazy_loader:keymap(mode, bind, opts) opts = opts or {} -- move the rerun arg to a seperate variable because keymap.set doesn't like @@ -85,7 +82,9 @@ function lazy:keymap(mode, bind, opts) self:cleanup() -- call the keymap after the user has mapped it - if rerun then + if type(rerun) == "function" then + rerun() + elseif rerun then local keys = vim.api.nvim_replace_termcodes(bind, true, false, true) vim.api.nvim_input(keys) end @@ -95,7 +94,7 @@ function lazy:keymap(mode, bind, opts) end --- cleanup all the callbacks, and load the plugin -function lazy:cleanup() +function lazy_loader:cleanup() -- cleanup user commands for _, command_id in pairs(self.command_ids) do local ok, err = pcall(vim.api.nvim_del_user_command, command_id) @@ -121,4 +120,4 @@ function lazy:cleanup() self:load() end -return lazy +return lazy_loader diff --git a/lua/dep/lazy/loader/short.lua b/lua/dep/lazy/loader/short.lua new file mode 100644 index 0000000..d6badde --- /dev/null +++ b/lua/dep/lazy/loader/short.lua @@ -0,0 +1,62 @@ +-- This file contains shorthands which rely on the loader core functions. They +-- are intended to ease lazy loading condition definitions to use them you may +-- do the following: +-- +-- ```lua +-- _G.dep_short = require("dep.lazy.loader.short") +-- ``` +-- +-- Which will allow you to reference it anywhere in your config like so: +-- +-- ```lua +-- require("dep") { +-- { "some/plugin", +-- lazy = dep_short.cmd("TheCommand") +-- } +-- } +-- ``` +-- +-- Happy vimming o/ +local short = {} + +--- create a single command +---@param name string the name of the command +---@param opts vim.api.keyset.user_command? options +---@return function callback +function short.cmd(name, opts) + return function(load) + load:cmd(name, opts) + end +end + +--- create a single auto command +---@param event string the event to trigger on +---@param opts vim.api.keyset.create_autocmd? options +---@return function callback +function short.auto(event, opts) + return function(load) + load:auto(event, opts) + end +end + +--- create a single auto command which will trigger on filetype +---@param filetype string filetype to register the auto on +---@return function callback +function short.ft(filetype) + return function(load) + load:ft(filetype) + end +end + +--- create a single keybind +---@param mode string the mode to trigger in +---@param bind string the binding to use +---@param opts lazy.Opts? options +---@return function callback +function short.keymap(mode, bind, opts) + return function(load) + load:keymap(mode, bind, opts) + end +end + +return short diff --git a/lua/dep/lazy/short.lua b/lua/dep/lazy/short.lua deleted file mode 100644 index d00fce2..0000000 --- a/lua/dep/lazy/short.lua +++ /dev/null @@ -1,43 +0,0 @@ ---- shorthands for when you only need to define one callback -local short = {} - ---- create a usercommand which will trigger the plugin to load ----@param name string the name of the command ----@param opts vim.api.keyset.user_command? options ----@return function callback lazy setup -function short:cmd(name, opts) - return function(load) - load:cmd(name, opts) - end -end - ---- create an auto command which will trigger the plugin to load ----@param event string the event to trigger on ----@param opts vim.api.keyset.create_autocmd? options ----@return function callback lazy setup -function short:auto(event, opts) - return function(load) - load:auto(event, opts) - end -end - ---- create an auto command which will trigger on filetype ----@param filetype string filetype to register the auto on -function short:ft(filetype) - return function(load) - load:ft(filetype) - end -end - ---- create a keybind which will trigger the plugin to load ----@param mode string the mode to trigger in ----@param bind string the binding to use ----@param opts vim.keymap.set.Opts? options ----@return function callback lazy setup -function short:keymap(mode, bind, opts) - return function(load) - load:keymap(mode, bind, opts) - end -end - -return short diff --git a/lua/dep/package.lua b/lua/dep/package.lua index e9345f8..5606dc7 100644 --- a/lua/dep/package.lua +++ b/lua/dep/package.lua @@ -15,7 +15,7 @@ local bench = require("dep.bench") ---@field on_config function[] table of functions to run on config ---@field on_setup function[] table of function to run on setup ---@field on_load function[] table of functions to run on load ----@field lazy_load function[] table of functions to run which will tell the package when to load +---@field lazy_load table table of functions and booleans to run which will tell the package when to load ---@field requirements package[] this package's requirements ---@field dependents package[] packages that require this package ---@field perf table performance metrics for the package @@ -299,7 +299,7 @@ function package:ensureadded(force) self.lazied = true for _, load_cond in pairs(self.lazy_load) do -- configure the lazy loader for the user - local l = require('dep.lazy.utils'):new() + local l = require('dep.lazy.loader'):new() if l == true then logger:log("lazy", "failed to get lazy utils") return false @@ -315,8 +315,14 @@ function package:ensureadded(force) loadpkg(self) end) - -- run it - load_cond(l) + -- run it if it's not just a stopper to keep the plugin lazy + if load_cond ~= true then + local ok, err = pcall(load_cond, l) + if not ok then + logger:log("lazy", "failed to register load conditions for '%s': %s", + self.name, err) + end + end end return self end diff --git a/lua/dep/spec.lua b/lua/dep/spec.lua index 951e654..e7b1d9d 100644 --- a/lua/dep/spec.lua +++ b/lua/dep/spec.lua @@ -15,7 +15,7 @@ local logger = require("dep.log") ---@field setup function? code to run before the package is loaded ---@field load function? code to run after the package is loaded ---@field config function? code to run after the package is installed/updated ----@field lazy function? code to run which determines when the package is loaded +---@field lazy function|true? code to run which determines when the package is loaded ---@field as string? overrides the short name of the package which is usually set --- to a substring of all the chars after "/" in spec[1] ---@field url string? the url to the git repository hosting the package @@ -114,8 +114,9 @@ function spec:check(silent) end if self.lazy ~= nil then -- spec.lazy - if type(self.lazy) ~= "function" then - logger:log("spec", "spec.lazy must be a function in %s", self[1]) + if type(self.lazy) ~= "function" and self.lazy ~= true then + logger:log("spec", "spec.lazy must be a function or boolean in %s", + self[1]) return false end end