summaryrefslogtreecommitdiff
path: root/script-beta/files.lua
diff options
context:
space:
mode:
Diffstat (limited to 'script-beta/files.lua')
-rw-r--r--script-beta/files.lua438
1 files changed, 0 insertions, 438 deletions
diff --git a/script-beta/files.lua b/script-beta/files.lua
deleted file mode 100644
index 4d34568d..00000000
--- a/script-beta/files.lua
+++ /dev/null
@@ -1,438 +0,0 @@
-local platform = require 'bee.platform'
-local config = require 'config'
-local glob = require 'glob'
-local furi = require 'file-uri'
-local parser = require 'parser'
-local proto = require 'proto'
-local lang = require 'language'
-local await = require 'await'
-local timer = require 'timer'
-
-local m = {}
-
-m.openMap = {}
-m.libraryMap = {}
-m.fileMap = {}
-m.watchList = {}
-m.notifyCache = {}
-m.assocVersion = -1
-m.assocMatcher = nil
-m.globalVersion = 0
-m.linesMap = setmetatable({}, { __mode = 'v' })
-m.astMap = setmetatable({}, { __mode = 'v' })
-
---- 打开文件
----@param uri string
-function m.open(uri)
- local originUri = uri
- if platform.OS == 'Windows' then
- uri = uri:lower()
- end
- m.openMap[uri] = true
- m.onWatch('open', originUri)
-end
-
---- 关闭文件
----@param uri string
-function m.close(uri)
- local originUri = uri
- if platform.OS == 'Windows' then
- uri = uri:lower()
- end
- m.openMap[uri] = nil
- m.onWatch('close', originUri)
-end
-
---- 是否打开
----@param uri string
----@return boolean
-function m.isOpen(uri)
- if platform.OS == 'Windows' then
- uri = uri:lower()
- end
- return m.openMap[uri] == true
-end
-
---- 标记为库文件
-function m.setLibraryPath(uri, libraryPath)
- if platform.OS == 'Windows' then
- uri = uri:lower()
- end
- m.libraryMap[uri] = libraryPath
-end
-
---- 是否是库文件
-function m.isLibrary(uri)
- if platform.OS == 'Windows' then
- uri = uri:lower()
- end
- return m.libraryMap[uri] ~= nil
-end
-
---- 获取库文件的根目录
-function m.getLibraryPath(uri)
- if platform.OS == 'Windows' then
- uri = uri:lower()
- end
- return m.libraryMap[uri]
-end
-
-function m.flushAllLibrary()
- m.libraryMap = {}
-end
-
---- 是否存在
----@return boolean
-function m.exists(uri)
- if platform.OS == 'Windows' then
- uri = uri:lower()
- end
- return m.fileMap[uri] ~= nil
-end
-
-function m.asKey(uri)
- if platform.OS == 'Windows' then
- uri = uri:lower()
- end
- return uri
-end
-
---- 设置文件文本
----@param uri string
----@param text string
-function m.setText(uri, text)
- if not text then
- return
- end
- local originUri = uri
- if platform.OS == 'Windows' then
- uri = uri:lower()
- end
- local create
- if not m.fileMap[uri] then
- m.fileMap[uri] = {
- uri = originUri,
- version = 0,
- }
- create = true
- end
- local file = m.fileMap[uri]
- if file.text == text then
- return
- end
- file.text = text
- m.linesMap[uri] = nil
- m.astMap[uri] = nil
- file.cache = {}
- file.cacheActiveTime = math.huge
- file.version = file.version + 1
- m.globalVersion = m.globalVersion + 1
- await.close('files.version')
- if create then
- m.onWatch('create', originUri)
- end
- m.onWatch('update', originUri)
-end
-
---- 获取文件版本
-function m.getVersion(uri)
- if platform.OS == 'Windows' then
- uri = uri:lower()
- end
- local file = m.fileMap[uri]
- if not file then
- return nil
- end
- return file.version
-end
-
---- 获取文件文本
----@param uri string
----@return string text
-function m.getText(uri)
- if platform.OS == 'Windows' then
- uri = uri:lower()
- end
- local file = m.fileMap[uri]
- if not file then
- return nil
- end
- return file.text
-end
-
---- 移除文件
----@param uri string
-function m.remove(uri)
- local originUri = uri
- if platform.OS == 'Windows' then
- uri = uri:lower()
- end
- local file = m.fileMap[uri]
- if not file then
- return
- end
- m.fileMap[uri] = nil
-
- m.globalVersion = m.globalVersion + 1
- await.close('files.version')
- m.onWatch('remove', originUri)
-end
-
---- 移除所有文件
-function m.removeAll()
- m.globalVersion = m.globalVersion + 1
- await.close('files.version')
- for uri in pairs(m.fileMap) do
- if not m.libraryMap[uri] then
- m.fileMap[uri] = nil
- m.astMap[uri] = nil
- m.linesMap[uri] = nil
- m.onWatch('remove', uri)
- end
- end
- --m.notifyCache = {}
-end
-
---- 移除所有关闭的文件
-function m.removeAllClosed()
- m.globalVersion = m.globalVersion + 1
- await.close('files.version')
- for uri in pairs(m.fileMap) do
- if not m.openMap[uri]
- and not m.libraryMap[uri] then
- m.fileMap[uri] = nil
- m.astMap[uri] = nil
- m.linesMap[uri] = nil
- m.onWatch('remove', uri)
- end
- end
- --m.notifyCache = {}
-end
-
---- 遍历文件
-function m.eachFile()
- return pairs(m.fileMap)
-end
-
-function m.compileAst(uri, text)
- if not m.isOpen(uri) and #text >= config.config.workspace.preloadFileSize * 1000 then
- if not m.notifyCache['preloadFileSize'] then
- m.notifyCache['preloadFileSize'] = {}
- m.notifyCache['skipLargeFileCount'] = 0
- end
- if not m.notifyCache['preloadFileSize'][uri] then
- m.notifyCache['preloadFileSize'][uri] = true
- m.notifyCache['skipLargeFileCount'] = m.notifyCache['skipLargeFileCount'] + 1
- if m.notifyCache['skipLargeFileCount'] <= 3 then
- local ws = require 'workspace'
- proto.notify('window/showMessage', {
- type = 3,
- message = lang.script('WORKSPACE_SKIP_LARGE_FILE'
- , ws.getRelativePath(uri)
- , config.config.workspace.preloadFileSize
- , #text / 1000
- ),
- })
- end
- end
- return nil
- end
- local clock = os.clock()
- local state, err = parser:compile(text
- , 'lua'
- , config.config.runtime.version
- , {
- special = config.config.runtime.special,
- }
- )
- local passed = os.clock() - clock
- if passed > 0.1 then
- log.warn(('Compile [%s] takes [%.3f] sec, size [%.3f] kb.'):format(uri, passed, #text / 1000))
- end
- if state then
- state.uri = uri
- state.ast.uri = uri
- if config.config.luadoc.enable then
- parser:luadoc(state)
- end
- return state
- else
- log.error(err)
- return nil
- end
-end
-
---- 获取文件语法树
----@param uri string
----@return table ast
-function m.getAst(uri)
- if platform.OS == 'Windows' then
- uri = uri:lower()
- end
- if uri ~= '' and not m.isLua(uri) then
- return nil
- end
- local file = m.fileMap[uri]
- if not file then
- return nil
- end
- local ast = m.astMap[uri]
- if not ast then
- ast = m.compileAst(uri, file.text)
- m.astMap[uri] = ast
- end
- file.cacheActiveTime = timer.clock()
- return ast
-end
-
---- 获取文件行信息
----@param uri string
----@return table lines
-function m.getLines(uri)
- if platform.OS == 'Windows' then
- uri = uri:lower()
- end
- local file = m.fileMap[uri]
- if not file then
- return nil
- end
- local lines = m.linesMap[uri]
- if not lines then
- lines = parser:lines(file.text)
- m.linesMap[uri] = lines
- end
- return lines
-end
-
---- 获取原始uri
-function m.getOriginUri(uri)
- if platform.OS == 'Windows' then
- uri = uri:lower()
- end
- local file = m.fileMap[uri]
- if not file then
- return nil
- end
- return file.uri
-end
-
-function m.getUri(uri)
- if platform.OS == 'Windows' then
- uri = uri:lower()
- end
- return uri
-end
-
---- 获取文件的自定义缓存信息(在文件内容更新后自动失效)
-function m.getCache(uri)
- if platform.OS == 'Windows' then
- uri = uri:lower()
- end
- local file = m.fileMap[uri]
- if not file then
- return nil
- end
- file.cacheActiveTime = timer.clock()
- return file.cache
-end
-
---- 判断文件名相等
-function m.eq(a, b)
- if platform.OS == 'Windows' then
- return a:lower() == b:lower()
- else
- return a == b
- end
-end
-
---- 获取文件关联
-function m.getAssoc()
- if m.assocVersion == config.version then
- return m.assocMatcher
- end
- m.assocVersion = config.version
- local patt = {}
- for k, v in pairs(config.other.associations) do
- if m.eq(v, 'lua') then
- patt[#patt+1] = k
- end
- end
- m.assocMatcher = glob.glob(patt)
- if platform.OS == 'Windows' then
- m.assocMatcher:setOption 'ignoreCase'
- end
- return m.assocMatcher
-end
-
---- 判断是否是Lua文件
----@param uri string
----@return boolean
-function m.isLua(uri)
- local ext = uri:match '%.([^%.%/%\\]-)$'
- if not ext then
- return false
- end
- if m.eq(ext, 'lua') then
- return true
- end
- local matcher = m.getAssoc()
- local path = furi.decode(uri)
- return matcher(path)
-end
-
---- 注册事件
-function m.watch(callback)
- m.watchList[#m.watchList+1] = callback
-end
-
-function m.onWatch(ev, ...)
- for _, callback in ipairs(m.watchList) do
- callback(ev, ...)
- end
-end
-
-function m.flushCache()
- for uri, file in pairs(m.fileMap) do
- file.cacheActiveTime = math.huge
- m.linesMap[uri] = nil
- m.astMap[uri] = nil
- file.cache = {}
- end
-end
-
-function m.flushFileCache(uri)
- if platform.OS == 'Windows' then
- uri = uri:lower()
- end
- local file = m.fileMap[uri]
- if not file then
- return
- end
- file.cacheActiveTime = math.huge
- m.linesMap[uri] = nil
- m.astMap[uri] = nil
- file.cache = {}
-end
-
-local function init()
- --TODO 可以清空文件缓存,之后看要不要启用吧
- --timer.loop(10, function ()
- -- local list = {}
- -- for _, file in pairs(m.fileMap) do
- -- if timer.clock() - file.cacheActiveTime > 10.0 then
- -- file.cacheActiveTime = math.huge
- -- file.ast = nil
- -- file.cache = {}
- -- list[#list+1] = file.uri
- -- end
- -- end
- -- if #list > 0 then
- -- log.info('Flush file caches:', #list, '\n', table.concat(list, '\n'))
- -- collectgarbage()
- -- end
- --end)
-end
-
-xpcall(init, log.error)
-
-return m