summaryrefslogtreecommitdiff
path: root/server-beta/src
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2019-09-23 14:54:04 +0800
committer最萌小汐 <sumneko@hotmail.com>2019-09-23 14:54:04 +0800
commit1dda93bba596496c1a427707fe97d92391129b8d (patch)
tree8bb525452d5677133a17662d091a077db5af1cad /server-beta/src
parent62a3e74b5467ca3bc0879e73e8fc8b129c0bec6a (diff)
downloadlua-language-server-1dda93bba596496c1a427707fe97d92391129b8d.zip
整理文件
Diffstat (limited to 'server-beta/src')
-rw-r--r--server-beta/src/config.lua194
-rw-r--r--server-beta/src/define/DiagnosticDefaultSeverity.lua21
-rw-r--r--server-beta/src/define/DiagnosticSeverity.lua6
-rw-r--r--server-beta/src/language.lua136
-rw-r--r--server-beta/src/proto/provider.lua20
-rw-r--r--server-beta/src/workspace/init.lua3
-rw-r--r--server-beta/src/workspace/workspace.lua9
7 files changed, 382 insertions, 7 deletions
diff --git a/server-beta/src/config.lua b/server-beta/src/config.lua
new file mode 100644
index 00000000..2da1762d
--- /dev/null
+++ b/server-beta/src/config.lua
@@ -0,0 +1,194 @@
+local util = require 'utility'
+local DiagnosticDefaultSeverity = require 'define.DiagnosticDefaultSeverity'
+
+local function Boolean(v)
+ if type(v) == 'boolean' then
+ return true, v
+ end
+ return false
+end
+
+local function Integer(v)
+ if type(v) == 'number' then
+ return true, math.floor(v)
+ end
+ return false
+end
+
+local function String(v)
+ return true, tostring(v)
+end
+
+local function Str2Hash(sep)
+ return function (v)
+ if type(v) == 'string' then
+ local t = {}
+ for s in v:gmatch('[^'..sep..']+') do
+ t[s] = true
+ end
+ return true, t
+ end
+ if type(v) == 'table' then
+ local t = {}
+ for _, s in ipairs(v) do
+ if type(s) == 'string' then
+ t[s] = true
+ end
+ end
+ return true, t
+ end
+ return false
+ end
+end
+
+local function Array(checker)
+ return function (tbl)
+ if type(tbl) ~= 'table' then
+ return false
+ end
+ local t = {}
+ for _, v in ipairs(tbl) do
+ local ok, result = checker(v)
+ if ok then
+ t[#t+1] = result
+ end
+ end
+ return true, t
+ end
+end
+
+local function Hash(keyChecker, valueChecker)
+ return function (tbl)
+ if type(tbl) ~= 'table' then
+ return false
+ end
+ local t = {}
+ for k, v in pairs(tbl) do
+ local ok1, key = keyChecker(k)
+ local ok2, value = valueChecker(v)
+ if ok1 and ok2 then
+ t[key] = value
+ end
+ end
+ if not next(t) then
+ return false
+ end
+ return true, t
+ end
+end
+
+local function Or(...)
+ local checkers = {...}
+ return function (obj)
+ for _, checker in ipairs(checkers) do
+ local suc, res = checker(obj)
+ if suc then
+ return true, res
+ end
+ end
+ return false
+ end
+end
+
+local ConfigTemplate = {
+ runtime = {
+ version = {'Lua 5.3', String},
+ library = {{}, Str2Hash ';'},
+ path = {{
+ "?.lua",
+ "?/init.lua",
+ "?/?.lua"
+ }, Array(String)},
+ },
+ diagnostics = {
+ enable = {true, Boolean},
+ globals = {{}, Str2Hash ';'},
+ disable = {{}, Str2Hash ';'},
+ severity = {
+ util.deepCopy(DiagnosticDefaultSeverity),
+ Hash(String, String),
+ },
+ },
+ workspace = {
+ ignoreDir = {{}, Str2Hash ';'},
+ ignoreSubmodules= {true, Boolean},
+ useGitIgnore = {true, Boolean},
+ maxPreload = {300, Integer},
+ preloadFileSize = {100, Integer},
+ library = {{}, Hash(
+ String,
+ Or(Boolean, Array(String))
+ )}
+ },
+ completion = {
+ enable = {true, Boolean},
+ callSnippet = {true, Boolean},
+ },
+ plugin = {
+ enable = {false, Boolean},
+ path = {'.vscode/lua-plugin/*.lua', String},
+ },
+}
+
+local OtherTemplate = {
+ associations = {{}, Hash(String, String)},
+ exclude = {{}, Hash(String, Boolean)},
+}
+
+local Config, Other
+
+local function init()
+ if Config then
+ return
+ end
+
+ Config = {}
+ for c, t in pairs(ConfigTemplate) do
+ Config[c] = {}
+ for k, info in pairs(t) do
+ Config[c][k] = info[1]
+ end
+ end
+
+ Other = {}
+ for k, info in pairs(OtherTemplate) do
+ Other[k] = info[1]
+ end
+end
+
+local function setConfig(self, config, other)
+ xpcall(function ()
+ for c, t in pairs(config) do
+ for k, v in pairs(t) do
+ local region = ConfigTemplate[c]
+ if region then
+ local info = region[k]
+ local suc, v = info[2](v)
+ if suc then
+ Config[c][k] = v
+ else
+ Config[c][k] = info[1]
+ end
+ end
+ end
+ end
+ for k, v in pairs(other) do
+ local info = OtherTemplate[k]
+ local suc, v = info[2](v)
+ if suc then
+ Other[k] = v
+ else
+ Other[k] = info[1]
+ end
+ end
+ log.debug('Config update: ', util.dump(Config), util.dump(Other))
+ end, log.error)
+end
+
+init()
+
+return {
+ setConfig = setConfig,
+ config = Config,
+ other = Other,
+}
diff --git a/server-beta/src/define/DiagnosticDefaultSeverity.lua b/server-beta/src/define/DiagnosticDefaultSeverity.lua
new file mode 100644
index 00000000..cc26cab2
--- /dev/null
+++ b/server-beta/src/define/DiagnosticDefaultSeverity.lua
@@ -0,0 +1,21 @@
+return {
+ ['unused-local'] = 'Hint',
+ ['unused-function'] = 'Hint',
+ ['undefined-global'] = 'Warning',
+ ['global-in-nil-env'] = 'Warning',
+ ['unused-label'] = 'Hint',
+ ['unused-vararg'] = 'Hint',
+ ['trailing-space'] = 'Hint',
+ ['redefined-local'] = 'Hint',
+ ['newline-call'] = 'Information',
+ ['redundant-parameter'] = 'Hint',
+ ['ambiguity-1'] = 'Warning',
+ ['lowercase-global'] = 'Information',
+ ['undefined-env-child'] = 'Information',
+ ['duplicate-index'] = 'Warning',
+ ['duplicate-method'] = 'Warning',
+ ['empty-block'] = 'Hint',
+ ['redundant-value'] = 'Hint',
+ ['emmy-lua'] = 'Warning',
+ ['set-const'] = 'Error',
+}
diff --git a/server-beta/src/define/DiagnosticSeverity.lua b/server-beta/src/define/DiagnosticSeverity.lua
new file mode 100644
index 00000000..05bd3659
--- /dev/null
+++ b/server-beta/src/define/DiagnosticSeverity.lua
@@ -0,0 +1,6 @@
+return {
+ Error = 1,
+ Warning = 2,
+ Information = 3,
+ Hint = 4,
+}
diff --git a/server-beta/src/language.lua b/server-beta/src/language.lua
new file mode 100644
index 00000000..3294c5b2
--- /dev/null
+++ b/server-beta/src/language.lua
@@ -0,0 +1,136 @@
+local fs = require 'bee.filesystem'
+local lni = require 'lni'
+
+local function supportLanguage()
+ local list = {}
+ for path in (ROOT / 'locale'):list_directory() do
+ if fs.is_directory(path) then
+ list[#list+1] = path:filename():string():lower()
+ end
+ end
+ return list
+end
+
+local function osLanguage()
+ return LANG:lower()
+end
+
+local function getLanguage(id)
+ local support = supportLanguage()
+ -- 检查是否支持语言
+ if support[id] then
+ return id
+ end
+ -- 根据语言的前2个字母来找近似语言
+ for _, lang in ipairs(support) do
+ if lang:sub(1, 2) == id:sub(1, 2) then
+ return lang
+ end
+ end
+ -- 使用英文
+ return 'enUS'
+end
+
+local function loadFileByLanguage(name, language)
+ local path = ROOT / 'locale' / language / (name .. '.lni')
+ local buf = io.load(path)
+ if not buf then
+ return {}
+ end
+ local suc, tbl = xpcall(lni, log.error, buf, path:string())
+ if not suc then
+ return {}
+ end
+ return tbl
+end
+
+local function formatAsArray(str, ...)
+ local index = 0
+ local args = {...}
+ return str:gsub('%{(.-)%}', function (pat)
+ local id, fmt
+ local pos = pat:find(':', 1, true)
+ if pos then
+ id = pat:sub(1, pos-1)
+ fmt = pat:sub(pos+1)
+ else
+ id = pat
+ fmt = 's'
+ end
+ id = tonumber(id)
+ if not id then
+ index = index + 1
+ id = index
+ end
+ return ('%'..fmt):format(args[id])
+ end)
+end
+
+local function formatAsTable(str, ...)
+ local args = ...
+ return str:gsub('%{(.-)%}', function (pat)
+ local id, fmt
+ local pos = pat:find(':', 1, true)
+ if pos then
+ id = pat:sub(1, pos-1)
+ fmt = pat:sub(pos+1)
+ else
+ id = pat
+ fmt = 's'
+ end
+ if not id then
+ return
+ end
+ return ('%'..fmt):format(args[id])
+ end)
+end
+
+local function loadLang(name, language)
+ local tbl = loadFileByLanguage(name, 'en-US')
+ if language ~= 'en-US' then
+ local other = loadFileByLanguage(name, language)
+ for k, v in pairs(other) do
+ tbl[k] = v
+ end
+ end
+ return setmetatable(tbl, {
+ __index = function (self, key)
+ self[key] = key
+ return key
+ end,
+ __call = function (self, key, ...)
+ local str = self[key]
+ local suc, res
+ if type(...) == 'table' then
+ suc, res = pcall(formatAsTable, str, ...)
+ else
+ suc, res = pcall(formatAsArray, str, ...)
+ end
+ if suc then
+ return res
+ else
+ -- 这里不能使用翻译,以免死循环
+ log.warn(('[%s][%s-%s] formated error: %s'):format(
+ language, name, key, str
+ ))
+ return str
+ end
+ end,
+ })
+end
+
+local function init()
+ local id = osLanguage()
+ local language = getLanguage(id)
+ log.info(('VSC language: %s'):format(id))
+ log.info(('LS language: %s'):format(language))
+ return setmetatable({ id = language }, {
+ __index = function (self, name)
+ local tbl = loadLang(name, language)
+ self[name] = tbl
+ return tbl
+ end,
+ })
+end
+
+return init()
diff --git a/server-beta/src/proto/provider.lua b/server-beta/src/proto/provider.lua
index 38428362..f5636a2f 100644
--- a/server-beta/src/proto/provider.lua
+++ b/server-beta/src/proto/provider.lua
@@ -1,13 +1,19 @@
-local util = require 'utility'
-local cap = require 'proto.capability'
-local pub = require 'pub'
-local task = require 'task'
-local files = require 'files'
-local proto = require 'proto.proto'
-local inte = require 'proto.interface'
+local util = require 'utility'
+local cap = require 'proto.capability'
+local pub = require 'pub'
+local task = require 'task'
+local files = require 'files'
+local proto = require 'proto.proto'
+local inte = require 'proto.interface'
+local workspace = require 'workspace'
proto.on('initialize', function (params)
--log.debug(util.dump(params))
+ if params.workspaceFolders then
+ local name = params.workspaceFolders[1].name
+ local uri = params.workspaceFolders[1].uri
+ workspace.init(name, uri)
+ end
return {
capabilities = cap.initer,
}
diff --git a/server-beta/src/workspace/init.lua b/server-beta/src/workspace/init.lua
new file mode 100644
index 00000000..7cbe15d7
--- /dev/null
+++ b/server-beta/src/workspace/init.lua
@@ -0,0 +1,3 @@
+local workspace = require 'workspace.workspace'
+
+return workspace
diff --git a/server-beta/src/workspace/workspace.lua b/server-beta/src/workspace/workspace.lua
new file mode 100644
index 00000000..d3669031
--- /dev/null
+++ b/server-beta/src/workspace/workspace.lua
@@ -0,0 +1,9 @@
+local m = {}
+m.type = 'workspace'
+
+function m.init(name, uri)
+ m.name = name
+ m.uri = uri
+end
+
+return m