range: extmarks/tsquery; renderer: text-change
All checks were successful
NeoVim tests / code-quality (push) Successful in 1m18s

This commit is contained in:
2025-06-11 20:04:46 -06:00
parent 12945a4cdf
commit 72b6886838
25 changed files with 1371 additions and 224 deletions

View File

@@ -6,19 +6,19 @@ M.debug = false
-- class Signal
--------------------------------------------------------------------------------
--- @class u.Signal
--- @class u.Signal<T>
--- @field name? string
--- @field private changing boolean
--- @field private value any
--- @field private value T
--- @field private subscribers table<function, boolean>
--- @field private on_dispose_callbacks function[]
local Signal = {}
M.Signal = Signal
Signal.__index = Signal
--- @param value any
--- @param value `T`
--- @param name? string
--- @return u.Signal
--- @return u.Signal<T>
function Signal:new(value, name)
local obj = setmetatable({
name = name,
@@ -30,7 +30,7 @@ function Signal:new(value, name)
return obj
end
--- @param value any
--- @param value T
function Signal:set(value)
self.value = value
@@ -67,11 +67,12 @@ function Signal:set(value)
end
end
--- @param value T
function Signal:schedule_set(value)
vim.schedule(function() self:set(value) end)
end
--- @return any
--- @return T
function Signal:get()
local ctx = M.ExecutionContext.current()
if ctx then ctx:track(self) end
@@ -85,8 +86,8 @@ function Signal:update(fn) self:set(fn(self.value)) end
function Signal:schedule_update(fn) self:schedule_set(fn(self.value)) end
--- @generic U
--- @param fn fun(value: T): U
--- @return u.Signal --<U>
--- @param fn fun(value: T): `U`
--- @return u.Signal<U>
function Signal:map(fn)
local mapped_signal = M.create_memo(function()
local value = self:get()
@@ -95,13 +96,13 @@ function Signal:map(fn)
return mapped_signal
end
--- @return u.Signal
--- @return u.Signal<T>
function Signal:clone()
return self:map(function(x) return x end)
end
--- @param fn fun(value: T): boolean
--- @return u.Signal -- <T>
--- @return u.Signal<T>
function Signal:filter(fn)
local filtered_signal = M.create_signal(nil, self.name and self.name .. ':filtered' or nil)
local unsubscribe_from_self = self:subscribe(function(value)
@@ -112,10 +113,10 @@ function Signal:filter(fn)
end
--- @param ms number
--- @return u.Signal -- <T>
--- @return u.Signal<T>
function Signal:debounce(ms)
local function set_timeout(timeout, callback)
local timer = (vim.uv or vim.loop).new_timer()
local timer = assert((vim.uv or vim.loop).new_timer(), 'could not create new timer')
timer:start(timeout, 0, function()
timer:stop()
timer:close()
@@ -127,7 +128,7 @@ function Signal:debounce(ms)
local filtered = M.create_signal(self.value, self.name and self.name .. ':debounced' or nil)
--- @diagnostic disable-next-line: undefined-doc-name
--- @type { queued: { value: T, ts: number }[]; timer?: uv_timer_t; }
--- @type { queued: { value: T, ts: number }[], timer?: uv.uv_timer_t }
local state = { queued = {}, timer = nil }
local function clear_timeout()
if state.timer == nil then return end
@@ -202,6 +203,7 @@ end
-- class ExecutionContext
--------------------------------------------------------------------------------
--- @type u.ExecutionContext|nil
local CURRENT_CONTEXT = nil
--- @class u.ExecutionContext
@@ -262,16 +264,18 @@ end
-- Helpers
--------------------------------------------------------------------------------
--- @param value any
--- @generic T
--- @param value `T`
--- @param name? string
--- @return u.Signal
--- @return u.Signal<T>
function M.create_signal(value, name) return Signal:new(value, name) end
--- @param fn function
--- @generic T
--- @param fn fun(): `T`
--- @param name? string
--- @return u.Signal
function M.create_memo(fn, name)
--- @type u.Signal
--- @type u.Signal<T> | nil
local result
local unsubscribe = M.create_effect(function()
local value = fn()
@@ -282,8 +286,8 @@ function M.create_memo(fn, name)
result = M.create_signal(value, name and ('m.s:' .. name) or nil)
end
end, name)
result:on_dispose(unsubscribe)
return result
assert(result):on_dispose(unsubscribe)
return assert(result)
end
--- @param fn function