Skip to content

Commit ca2b5de

Browse files
committed
feat: add fzy filtering, cache and skeleton code for :Lux
1 parent 06e50f7 commit ca2b5de

3 files changed

Lines changed: 516 additions & 0 deletions

File tree

lua/lux-nvim/cache.lua

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
---@mod lux.cache lux.nvim package cache
2+
---
3+
---@brief [[
4+
---
5+
---Cached package state.
6+
---
7+
---@brief ]]
8+
9+
local cache = {}
10+
11+
local config = require("lux-nvim.config")
12+
local nio = require("nio")
13+
14+
---@type table<package, Package[]> | nil
15+
local _cached_packages = nil
16+
17+
---@type table<package_name, Package[]> | nil
18+
local _cached_dev_binaries = nil
19+
20+
---Used for completions only
21+
---@type string[] | nil
22+
local _removable_package_cache = nil
23+
24+
---@type table<package_name, OutdatedPackage> | nil
25+
local _outdated_package_cache = nil
26+
27+
---Tries to get the cached value
28+
---Returns an empty list if the cache is not ready,
29+
---and triggers an async task to populate the cache.
30+
---WARNING: `cache_ref` MUST be populated by `populate`
31+
---
32+
---@generic T
33+
---@param cache_ref T
34+
---@param populate async fun():T Stateul
35+
---@return table<string, T> result indexed by name
36+
local function try_get_unsafe(cache_ref, populate)
37+
if not cache_ref then
38+
nio.run(populate)
39+
local result = vim.empty_dict()
40+
return result
41+
end
42+
return cache_ref
43+
end
44+
45+
---Query luarocks packages and populate the cache.
46+
---@type async fun()
47+
cache.populate_cached_packages = nio.create(function()
48+
if _cached_packages then
49+
return
50+
end
51+
luarocks.search_all(function(packages)
52+
if not vim.tbl_isempty(packages) then
53+
_cached_packages = packages
54+
vim.schedule(function()
55+
vim.api.nvim_exec_autocmds("User", {
56+
pattern = "LuxCachePopulated",
57+
modeline = false,
58+
data = _cached_packages,
59+
})
60+
end)
61+
end
62+
end, {
63+
dev = true,
64+
})
65+
end)
66+
67+
---Tries to get the cached packages.
68+
---Returns an empty list if the cache is not ready,
69+
---and triggers an async task to populate the cache.
70+
---@return table<string, Package[]> packages indexed by name
71+
function cache.try_get_packages()
72+
return try_get_unsafe(_cached_packages, cache.populate_cached_packages)
73+
end
74+
75+
---Query the state for packages that can be removed
76+
---and populate the cache.
77+
---@type async fun()
78+
cache.populate_removable_package_cache = nio.create(function()
79+
if _removable_package_cache then
80+
return
81+
end
82+
_removable_package_cache = state.query_removable_packages()
83+
vim.schedule(function()
84+
vim.api.nvim_exec_autocmds("User", {
85+
pattern = "LuxRemovablePackageCachePopulated",
86+
modeline = false,
87+
data = _removable_package_cache,
88+
})
89+
end)
90+
end)
91+
92+
---Tries to get the cached removable packages.
93+
---Returns an empty list if the cache is not ready,
94+
---and triggers an async task to populate the cache.
95+
---@return table<string, Package[]> packages indexed by name
96+
function cache.try_get_removable_packages()
97+
return try_get_unsafe(_removable_package_cache, cache.populate_removable_package_cache)
98+
end
99+
100+
---Invalidate the removable package cache
101+
cache.invalidate_removable_packages = function()
102+
_removable_package_cache = nil
103+
end
104+
105+
---Query the state for packages that can be removed
106+
---and populate the cache.
107+
---@type async fun()
108+
cache.populate_outdated_package_cache = nio.create(function()
109+
if _outdated_package_cache then
110+
return
111+
end
112+
_outdated_package_cache = state.outdated_packages()
113+
vim.schedule(function()
114+
vim.api.nvim_exec_autocmds("User", {
115+
pattern = "LuxOutdatedPackageCachePopulated",
116+
modeline = false,
117+
data = _outdated_package_cache,
118+
})
119+
end)
120+
end)
121+
122+
---Populate all package state caches
123+
cache.populate_all_package_state_caches = nio.create(function()
124+
cache.populate_removable_package_cache()
125+
cache.populate_outdated_package_cache()
126+
end)
127+
---Tries to get the cached removable packages.
128+
---Returns an empty list if the cache is not ready,
129+
---and triggers an async task to populate the cache.
130+
---@return table<string, OutdatedPackage> packages indexed by name
131+
function cache.try_get_outdated_packages()
132+
return try_get_unsafe(_outdated_package_cache, cache.populate_outdated_package_cache)
133+
end
134+
135+
---Search the cache for rocks-binaries-dev packages.
136+
---Repopulates the cache and runs a second search if not found
137+
---@type async fun(package_name: string, version: string?)
138+
cache.search_binary_dev_packages = nio.create(function(package_name, version)
139+
---@cast package_name package_name
140+
---@cast version string
141+
local function search_cache()
142+
local packages
143+
if _cached_dev_binaries then
144+
packages = _cached_dev_binaries[package_name]
145+
end
146+
return packages
147+
and vim.iter(packages):any(function(package)
148+
---@cast package Package
149+
if version == "dev" then
150+
version = "scm"
151+
end
152+
return not version or package.version == version
153+
end)
154+
end
155+
local found = search_cache()
156+
if found then
157+
return found
158+
end
159+
local future = nio.control.future()
160+
luarocks.search_all(function(result)
161+
if not vim.tbl_isempty(result) then
162+
_cached_dev_binaries = result
163+
end
164+
future.set(true)
165+
end, {
166+
servers = config.get_dev_servers(),
167+
})
168+
future.wait()
169+
return search_cache()
170+
end, 2)
171+
172+
return cache

0 commit comments

Comments
 (0)