diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2020-11-20 21:57:09 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2020-11-20 21:57:09 +0800 |
commit | 4ca61ec457822dd14966afa0752340ae8ce180a1 (patch) | |
tree | ae8adb1ad82c717868e551e699fd3cf3bb290089 /script-beta/fs-utility.lua | |
parent | c63b2e404d8d2bb984afe3678a5ba2b2836380cc (diff) | |
download | lua-language-server-4ca61ec457822dd14966afa0752340ae8ce180a1.zip |
no longer beta
Diffstat (limited to 'script-beta/fs-utility.lua')
-rw-r--r-- | script-beta/fs-utility.lua | 559 |
1 files changed, 0 insertions, 559 deletions
diff --git a/script-beta/fs-utility.lua b/script-beta/fs-utility.lua deleted file mode 100644 index 42041734..00000000 --- a/script-beta/fs-utility.lua +++ /dev/null @@ -1,559 +0,0 @@ -local fs = require 'bee.filesystem' -local platform = require 'bee.platform' - -local type = type -local ioOpen = io.open -local pcall = pcall -local pairs = pairs -local setmetatable = setmetatable -local next = next -local ipairs = ipairs -local tostring = tostring -local tableSort = table.sort - -_ENV = nil - -local m = {} ---- 读取文件 ----@param path string -function m.loadFile(path) - if type(path) ~= 'string' then - path = path:string() - end - local f, e = ioOpen(path, 'rb') - if not f then - return nil, e - end - if f:read(3) ~= '\xEF\xBB\xBF' then - f:seek("set") - end - local buf = f:read 'a' - f:close() - return buf -end - ---- 写入文件 ----@param path string ----@param content string -function m.saveFile(path, content) - if type(path) ~= 'string' then - path = path:string() - end - local f, e = ioOpen(path, "wb") - - if f then - f:write(content) - f:close() - return true - else - return false, e - end -end - -local function buildOptional(optional) - optional = optional or {} - optional.add = optional.add or {} - optional.del = optional.del or {} - optional.mod = optional.mod or {} - optional.err = optional.err or {} - return optional -end - -local function split(str, sep) - local t = {} - local current = 1 - while current <= #str do - local s, e = str:find(sep, current) - if not s then - t[#t+1] = str:sub(current) - break - end - if s > 1 then - t[#t+1] = str:sub(current, s - 1) - end - current = e + 1 - end - return t -end - -local dfs = {} -dfs.__index = dfs -dfs.type = 'dummy' -dfs.path = '' - -function m.dummyFS(t) - return setmetatable({ - files = t or {}, - }, dfs) -end - -function dfs:__tostring() - return 'dummy:' .. tostring(self.path) -end - -function dfs:__div(filename) - if type(filename) ~= 'string' then - filename = filename:string() - end - local new = m.dummyFS(self.files) - if self.path:sub(-1):match '[^/\\]' then - new.path = self.path .. '\\' .. filename - else - new.path = self.path .. filename - end - return new -end - -function dfs:_open(index) - local paths = split(self.path, '[/\\]') - local current = self.files - if not index then - index = #paths - elseif index < 0 then - index = #paths + index + 1 - end - for i = 1, index do - local path = paths[i] - if current[path] then - current = current[path] - else - return nil - end - end - return current -end - -function dfs:_filename() - return self.path:match '[^/\\]+$' -end - -function dfs:parent_path() - local new = m.dummyFS(self.files) - if self.path:find('[/\\]') then - new.path = self.path:gsub('[/\\]+[^/\\]*$', '') - else - new.path = '' - end - return new -end - -function dfs:filename() - local new = m.dummyFS(self.files) - new.path = self:_filename() - return new -end - -function dfs:string() - return self.path -end - -function dfs:list_directory() - local dir = self:_open() - if type(dir) ~= 'table' then - return function () end - end - local keys = {} - for k in pairs(dir) do - keys[#keys+1] = k - end - tableSort(keys) - local i = 0 - return function () - i = i + 1 - local k = keys[i] - if not k then - return nil - end - return self / k - end -end - -function dfs:isDirectory() - local target = self:_open() - if type(target) == 'table' then - return true - end - return false -end - -function dfs:remove() - local dir = self:_open(-2) - local filename = self:_filename() - if not filename then - return - end - dir[filename] = nil -end - -function dfs:exists() - local target = self:_open() - return target ~= nil -end - -function dfs:createDirectories(path) - if type(path) ~= 'string' then - path = path:string() - end - local paths = split(path, '[/\\]') - local current = self.files - for i = 1, #paths do - local sub = paths[i] - if current[sub] then - if type(current[sub]) ~= 'table' then - return false - end - else - current[sub] = {} - end - current = current[sub] - end - return true -end - -function dfs:saveFile(path, text) - if type(path) ~= 'string' then - path = path:string() - end - local temp = m.dummyFS(self.files) - temp.path = path - local dir = temp:_open(-2) - if not dir then - return false, '无法打开:' .. path - end - local filename = temp:_filename() - if not filename then - return false, '无法打开:' .. path - end - if type(dir[filename]) == 'table' then - return false, '无法打开:' .. path - end - dir[filename] = text -end - -local function fsAbsolute(path, optional) - if type(path) == 'string' then - local suc, res = pcall(fs.path, path) - if not suc then - optional.err[#optional.err+1] = res - return nil - end - path = res - elseif type(path) == 'table' then - return path - end - local suc, res = pcall(fs.absolute, path) - if not suc then - optional.err[#optional.err+1] = res - return nil - end - return res -end - -local function fsIsDirectory(path, optional) - if path.type == 'dummy' then - return path:isDirectory() - end - local suc, res = pcall(fs.is_directory, path) - if not suc then - optional.err[#optional.err+1] = res - return false - end - return res -end - -local function fsRemove(path, optional) - if path.type == 'dummy' then - return path:remove() - end - local suc, res = pcall(fs.remove, path) - if not suc then - optional.err[#optional.err+1] = res - end - optional.del[#optional.del+1] = path:string() -end - -local function fsExists(path, optional) - if path.type == 'dummy' then - return path:exists() - end - local suc, res = pcall(fs.exists, path) - if not suc then - optional.err[#optional.err+1] = res - return false - end - return res -end - -local function fsSave(path, text, optional) - if path.type == 'dummy' then - local dir = path:_open(-2) - if not dir then - optional.err[#optional.err+1] = '无法打开:' .. path:string() - return false - end - local filename = path:_filename() - if not filename then - optional.err[#optional.err+1] = '无法打开:' .. path:string() - return false - end - if type(dir[filename]) == 'table' then - optional.err[#optional.err+1] = '无法打开:' .. path:string() - return false - end - dir[filename] = text - else - local suc, err = m.saveFile(path, text) - if suc then - return true - end - optional.err[#optional.err+1] = err - return false - end -end - -local function fsLoad(path, optional) - if path.type == 'dummy' then - local text = path:_open() - if type(text) == 'string' then - return text - else - optional.err[#optional.err+1] = '无法打开:' .. path:string() - return nil - end - else - local text, err = m.loadFile(path) - if text then - return text - else - optional.err[#optional.err+1] = err - return nil - end - end -end - -local function fsCopy(source, target, optional) - if source.type == 'dummy' then - local sourceText = source:_open() - if not sourceText then - optional.err[#optional.err+1] = '无法打开:' .. source:string() - return false - end - return fsSave(target, sourceText, optional) - else - if target.type == 'dummy' then - local sourceText, err = m.loadFile(source) - if not sourceText then - optional.err[#optional.err+1] = err - return false - end - return fsSave(target, sourceText, optional) - else - local suc, res = pcall(fs.copy_file, source, target, true) - if not suc then - optional.err[#optional.err+1] = res - return false - end - end - end - return true -end - -local function fsCreateDirectories(path, optional) - if path.type == 'dummy' then - return path:createDirectories() - end - local suc, res = pcall(fs.create_directories, path) - if not suc then - optional.err[#optional.err+1] = res - return false - end - return true -end - -local function fileRemove(path, optional) - if optional.onRemove and optional.onRemove(path) == false then - return - end - if fsIsDirectory(path, optional) then - for child in path:list_directory() do - fileRemove(child, optional) - end - end - if fsRemove(path, optional) then - optional.del[#optional.del+1] = path:string() - end -end - -local function fileCopy(source, target, optional) - if optional.onCopy and optional.onCopy(source, target) == false then - return - end - local isDir1 = fsIsDirectory(source, optional) - local isDir2 = fsIsDirectory(target, optional) - local isExists = fsExists(target, optional) - if isDir1 then - if isDir2 or fsCreateDirectories(target, optional) then - for filePath in source:list_directory() do - local name = filePath:filename():string() - fileCopy(filePath, target / name, optional) - end - end - else - if isExists and not isDir2 then - local buf1 = fsLoad(source, optional) - local buf2 = fsLoad(target, optional) - if buf1 and buf2 then - if buf1 ~= buf2 then - if fsCopy(source, target, optional) then - optional.mod[#optional.mod+1] = target:string() - end - end - end - else - if fsCopy(source, target, optional) then - optional.add[#optional.add+1] = target:string() - end - end - end -end - -local function fileSync(source, target, optional) - if optional.onSync and optional.onSync(source, target) == false then - return - end - local isDir1 = fsIsDirectory(source, optional) - local isDir2 = fsIsDirectory(target, optional) - local isExists = fsExists(target, optional) - if isDir1 then - if isDir2 then - local fileList = m.fileList() - for filePath in target:list_directory() do - fileList[filePath] = true - end - for filePath in source:list_directory() do - local name = filePath:filename():string() - local targetPath = target / name - fileSync(filePath, targetPath, optional) - fileList[targetPath] = nil - end - for path in pairs(fileList) do - fileRemove(path, optional) - end - else - if isExists then - fileRemove(target, optional) - end - if fsCreateDirectories(target) then - for filePath in source:list_directory() do - local name = filePath:filename():string() - fileCopy(filePath, target / name, optional) - end - end - end - else - if isDir2 then - fileRemove(target, optional) - end - if isExists then - local buf1 = fsLoad(source, optional) - local buf2 = fsLoad(target, optional) - if buf1 and buf2 then - if buf1 ~= buf2 then - if fsCopy(source, target, optional) then - optional.mod[#optional.mod+1] = target:string() - end - end - end - else - if fsCopy(source, target, optional) then - optional.add[#optional.add+1] = target:string() - end - end - end -end - ---- 文件列表 -function m.fileList(optional) - optional = optional or buildOptional(optional) - local os = platform.OS - local keyMap = {} - local fileList = {} - local function computeKey(path) - path = fsAbsolute(path, optional) - if not path then - return nil - end - local key - if os == 'Windows' then - key = path:string():lower() - else - key = path:string() - end - return key - end - return setmetatable({}, { - __index = function (_, path) - local key = computeKey(path) - return fileList[key] - end, - __newindex = function (_, path, value) - local key = computeKey(path) - if not key then - return - end - if value == nil then - keyMap[key] = nil - else - keyMap[key] = path - fileList[key] = value - end - end, - __pairs = function () - local key, path - return function () - key, path = next(keyMap, key) - return path, fileList[key] - end - end, - }) -end - ---- 删除文件(夹) -function m.fileRemove(path, optional) - optional = buildOptional(optional) - path = fsAbsolute(path, optional) - - fileRemove(path, optional) - - return optional -end - ---- 复制文件(夹) ----@param source string ----@param target string ----@return table -function m.fileCopy(source, target, optional) - optional = buildOptional(optional) - source = fsAbsolute(source, optional) - target = fsAbsolute(target, optional) - - fileCopy(source, target, optional) - - return optional -end - ---- 同步文件(夹) ----@param source string ----@param target string ----@return table -function m.fileSync(source, target, optional) - optional = buildOptional(optional) - source = fsAbsolute(source, optional) - target = fsAbsolute(target, optional) - - fileSync(source, target, optional) - - return optional -end - -return m |