mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-02-03 06:50:05 +08:00
55 lines
1.4 KiB
Lua
55 lines
1.4 KiB
Lua
--- I like context managers for Python
|
|
--- I want them in Lua.
|
|
|
|
local context_manager = {}
|
|
|
|
function context_manager.with(obj, callable)
|
|
-- Wrap functions for people since we're nice
|
|
if type(obj) == "function" then
|
|
obj = coroutine.create(obj)
|
|
end
|
|
|
|
if type(obj) == "thread" then
|
|
local ok, context = coroutine.resume(obj)
|
|
assert(ok, "Should have yielded in coroutine.")
|
|
|
|
local result = callable(context)
|
|
|
|
local done, _ = coroutine.resume(obj)
|
|
assert(done, "Should be done")
|
|
|
|
local no_other = not coroutine.resume(obj)
|
|
assert(no_other, "Should not yield anymore, otherwise that would make things complicated")
|
|
|
|
return result
|
|
else
|
|
assert(obj.enter)
|
|
assert(obj.exit)
|
|
|
|
-- TODO: Callable can be string for vimL function or a lua callable
|
|
local context = obj:enter()
|
|
local result = callable(context)
|
|
obj:exit()
|
|
|
|
return result
|
|
end
|
|
end
|
|
|
|
--- @param filename string|table -- If string, used as io.open(filename)
|
|
--- Else, should be a table with `filename` as an attribute
|
|
function context_manager.open(filename, mode)
|
|
if type(filename) == "table" and filename.filename then
|
|
filename = filename.filename
|
|
end
|
|
|
|
local file_io = assert(io.open(filename, mode))
|
|
|
|
return coroutine.create(function()
|
|
coroutine.yield(file_io)
|
|
|
|
file_io:close()
|
|
end)
|
|
end
|
|
|
|
return context_manager
|