v4k-git-backup/tools/editor/art/lite/data/plugins/fsutils.lua

167 lines
3.8 KiB
Lua

-- mod-version:1 -- lite-xl 1.16
local core = require "core"
local common = require "core.common"
local command = require "core.command"
local fsutils = {}
function fsutils.iterdir(dir)
local stack = { dir }
return function()
local path = table.remove(stack)
if not path then return end
for _, file in ipairs(system.list_dir(path) or {}) do
stack[#stack + 1] = path .. PATHSEP .. file
end
return path, system.get_file_info(path)
end
end
function fsutils.delete(dir, yield)
local dirs = {}
local n = 0
for filename, stat in fsutils.iterdir(dir) do
if stat.type == "dir" then
-- this will later allow us to delete the dirs in correct sequence
table.insert(dirs, filename)
else
os.remove(filename)
if yield then
n = n + 1
coroutine.yield(n)
end
end
end
for i = #dirs, 1, -1 do
os.remove(dirs[i])
if yield then
n = n + 1
coroutine.yield(n)
end
end
end
function fsutils.move(oldname, newname)
os.rename(oldname, newname)
end
function fsutils.split(path)
local segments = {}
local pos = 1
while true do
local s, e = string.find(path, "[/\\]+", pos)
if not s then break end
table.insert(segments, string.sub(path, pos, s - 1))
pos = e + 1
end
table.insert(list, string.sub(path, pos))
if segments[#segments] == '' then
table.remove(segments)
end
return segments
end
function fsutils.normalize(path)
return table.concat(fsutils.split(path), PATHSEP)
end
function fsutils.normalize_posix(path)
return table.concat(fsutils.split(path), '/')
end
function fsutils.mkdir(path)
local segments = fsutils.split(path)
if system.mkdir then
local p = ""
for i = 1, #segments do
p = table.concat(segments, PATHSEP, 1, i)
end
if p == "" then
return nil, "path empty", p
end
local stat = system.get_file_info(p)
if stat and stat.type == "file" then
return nil, "path exists as a file", p
end
local ok, err = system.mkdir(p)
if not ok then
return nil, err, p
end
else
-- just wing it lol
system.exec(string.format(PLATFORM == "Windows" and "setlocal enableextensions & mkdir %q" or "mkdir -p %q", fsutils.normalize(path)))
end
end
local function async_exec(f, cb)
cb = cb or function() end
local co = coroutine.create(f)
local function resolve(...)
local ok, exec_body = coroutine.resume(co, ...)
if not ok then
error(debug.traceback(co, exec_body))
end
if coroutine.status(co) ~= "dead" then
exec_body(resolve)
end
end
resolve(cb)
end
local function prompt(text, suggest)
return coroutine.yield(function(resolve)
core.command_view:enter(text, resolve, suggest)
end)
end
command.add(nil, {
["files:delete"] = function()
async_exec(function()
local path = prompt("Delete", common.path_suggest)
core.add_thread(function()
-- we use a wrapping coroutine to get status
local function delete()
return coroutine.wrap(function() fsutils.delete(path, true) end)
end
for n in delete() do
if n % 100 == 0 then
core.log("Deleted %d items...", n)
coroutine.yield()
end
end
core.log("%q deleted.", path)
end)
end)
end,
["files:move"] = function()
async_exec(function()
local oldname = prompt("Move", common.path_suggest)
local newname = prompt("To", common.path_suggest)
fsutils.move(oldname, newname)
core.log("Moved %q to %q", oldname, newname)
end)
end
})
if not command.map["files:create-directory"] then
command.add(nil, {
["files:create-directory"] = function()
async_exec(function()
local path = prompt("Name", common.path_suggest)
fsutils.mkdir(path)
core.log("%q created.", path)
end)
end
})
end
return fsutils