@@ -8,11 +8,11 @@ local DEFAULT_ERROR = "Unkown error."
88
99local M = {}
1010
11- --- @private
11+ --- @package
1212--- @type { [Future] : boolean }
1313M ._watching = setmetatable ({}, { __mode = " k" })
1414
15- --- @private
15+ --- @package
1616--- @type { [thread] : Future }
1717M ._handles = {}
1818
6565
6666--- @class Waitable : diffview.Object
6767local Waitable = oop .create_class (" Waitable" )
68+ M .Waitable = Waitable
6869
6970--- @abstract
7071--- @return any ... # Any values returned by the waitable
7172function Waitable :await () oop .abstract_stub () end
7273
73- M .Waitable = Waitable
74+ --- Schedule a callback to be invoked when this waitable has settled.
75+ --- @param callback function
76+ function Waitable :finally (callback )
77+ (M .void (function ()
78+ local ret = tbl_pack (M .await (self ))
79+ callback (tbl_unpack (ret ))
80+ end ))()
81+ end
7482
7583--- @class Future : Waitable
7684--- @operator call : Future
77- --- @field private thread thread
78- --- @field private listeners Future[]
79- --- @field private parent ? Future
80- --- @field private func ? function
81- --- @field private return_values ? any[]
82- --- @field private err ? string
83- --- @field private kind AsyncKind
84- --- @field private started boolean
85- --- @field private awaiting_cb boolean
86- --- @field private done boolean
87- --- @field private has_raised boolean # `true` if this future has raised an error.
85+ --- @field package thread thread
86+ --- @field package listeners Future[]
87+ --- @field package parent ? Future
88+ --- @field package func ? function
89+ --- @field package return_values ? any[]
90+ --- @field package err ? string
91+ --- @field package kind AsyncKind
92+ --- @field package started boolean
93+ --- @field package awaiting_cb boolean
94+ --- @field package done boolean
95+ --- @field package has_raised boolean # `true` if this future has raised an error.
8896local Future = oop .create_class (" Future" , Waitable )
8997
9098function Future :init (opt )
@@ -107,18 +115,18 @@ function Future:init(opt)
107115 self .has_raised = false
108116end
109117
110- --- @private
118+ --- @package
111119--- @return string
112120function Future :__tostring ()
113121 return dstring (self .thread )
114122end
115123
116- --- @private
124+ --- @package
117125function Future :destroy ()
118126 M ._handles [self .thread ] = nil
119127end
120128
121- --- @private
129+ --- @package
122130--- @param value boolean
123131function Future :set_done (value )
124132 self .done = value
@@ -138,7 +146,7 @@ function Future:get_returned()
138146 return unpack (self .return_values , 2 , table.maxn (self .return_values ))
139147end
140148
141- --- @private
149+ --- @package
142150--- @param ... any
143151function Future :dprint (...)
144152 if not DiffviewGlobal .logger then return end
@@ -149,7 +157,7 @@ function Future:dprint(...)
149157 end
150158end
151159
152- --- @private
160+ --- @package
153161--- @param ... any
154162function Future :dprintf (...)
155163 self :dprint (fmt (... ))
@@ -165,21 +173,21 @@ function Future:unwatch()
165173 M ._watching [self ] = nil
166174end
167175
168- --- @private
176+ --- @package
169177--- @return boolean
170178function Future :is_watching ()
171179 return not not M ._watching [self ]
172180end
173181
174- --- @private
182+ --- @package
175183--- @param force ? boolean
176184function Future :raise (force )
177185 if self .has_raised and not force then return end
178186 self .has_raised = true
179187 error (self .err )
180188end
181189
182- --- @private
190+ --- @package
183191function Future :step (...)
184192 self :dprint (" step" )
185193 local ret = { coroutine.resume (self .thread , ... ) }
@@ -217,7 +225,7 @@ function Future:step(...)
217225 end
218226end
219227
220- --- @private
228+ --- @package
221229--- @param ok boolean
222230--- @param ... any
223231function Future :notify_all (ok , ...)
@@ -241,6 +249,7 @@ function Future:notify_all(ok, ...)
241249 end
242250end
243251
252+ --- @override
244253--- @return any ... # Return values
245254function Future :await ()
246255 if self .err then
@@ -302,7 +311,7 @@ function Future:await()
302311 return self :get_returned ()
303312end
304313
305- --- @private
314+ --- @package
306315--- @return any ...
307316function Future :toplevel_await ()
308317 local ok , status
@@ -337,15 +346,13 @@ end
337346--- @field nparams ? integer
338347--- @field args any[]
339348
340- --- @private
349+ --- @package
341350--- @param func function
342351--- @param opt async ._run.Opt
343352function M ._run (func , opt )
344- --- @diagnostic disable : invisible
345353 opt = opt or {}
346354
347355 local handle --- @type Future
348- local wrapped_cb
349356 local use_err_handler = not not current_thread ()
350357
351358 local function wrapped_func (...)
@@ -381,7 +388,7 @@ function M._run(func, opt)
381388 if opt .kind == " callback" then
382389 local cur_cb = opt .args [opt .nparams ]
383390
384- function wrapped_cb (...)
391+ local function wrapped_cb (...)
385392 handle :set_done (true )
386393 handle .return_values = { true , ... }
387394 if cur_cb then cur_cb (... ) end
@@ -405,7 +412,6 @@ function M._run(func, opt)
405412 handle :step (tbl_unpack (opt .args ))
406413
407414 return handle
408- --- @diagnostic enable : invisible
409415end
410416
411417--- Create an async task for a function with no return values.
@@ -566,4 +572,6 @@ M.scheduler = M.wrap(function(fast_only, callback)
566572 vim .schedule (callback )
567573end )
568574
575+ M .schedule_now = M .wrap (vim .schedule , 1 )
576+
569577return M
0 commit comments