diff options
-rw-r--r-- | changelog.md | 2 | ||||
-rw-r--r-- | locale/en-us/script.lua | 2 | ||||
-rw-r--r-- | locale/pt-br/script.lua | 2 | ||||
-rw-r--r-- | locale/zh-cn/script.lua | 2 | ||||
-rw-r--r-- | locale/zh-tw/script.lua | 2 | ||||
-rw-r--r-- | script/client.lua | 80 | ||||
-rw-r--r-- | test/tclient/tests/modify-luarc.lua | 150 |
7 files changed, 226 insertions, 14 deletions
diff --git a/changelog.md b/changelog.md index d3c78de9..50685423 100644 --- a/changelog.md +++ b/changelog.md @@ -1,8 +1,10 @@ # changelog ## 3.6.5 +* `FIX` [#831] * `FIX` [#1729] +[#831]: https://github.com/sumneko/lua-language-server/issues/831 [#1729]: https://github.com/sumneko/lua-language-server/issues/1729 `2022-11-29` diff --git a/locale/en-us/script.lua b/locale/en-us/script.lua index a75f2301..fb203d7e 100644 --- a/locale/en-us/script.lua +++ b/locale/en-us/script.lua @@ -562,6 +562,8 @@ CONFIG_LOAD_ERROR = 'Setting file loading error: {}' CONFIG_TYPE_ERROR = 'The setting file must be in lua or json format: {}' +CONFIG_MODIFY_FAIL_SYNTAX_ERROR = +'Failed to modify settings, there are syntax errors in the settings file: {}' PLUGIN_RUNTIME_ERROR = [[ diff --git a/locale/pt-br/script.lua b/locale/pt-br/script.lua index 5ae052d2..aabb3a19 100644 --- a/locale/pt-br/script.lua +++ b/locale/pt-br/script.lua @@ -562,6 +562,8 @@ CONFIG_LOAD_ERROR = 'Configurando o erro de carregamento do arquivo: {}' CONFIG_TYPE_ERROR = 'O arquivo de configuração deve estar no formato LUA ou JSON: {}' +CONFIG_MODIFY_FAIL_SYNTAX_ERROR = -- TODO: need translate! +'Failed to modify settings, there are syntax errors in the settings file: {}' PLUGIN_RUNTIME_ERROR = [[ diff --git a/locale/zh-cn/script.lua b/locale/zh-cn/script.lua index a9905e35..6adaa17d 100644 --- a/locale/zh-cn/script.lua +++ b/locale/zh-cn/script.lua @@ -562,6 +562,8 @@ CONFIG_LOAD_ERROR = '设置文件加载错误:{}' CONFIG_TYPE_ERROR = '设置文件必须是lua或json格式:{}' +CONFIG_MODIFY_FAIL_SYNTAX_ERROR = +'修改设置失败,设置文件中有语法错误:{}' PLUGIN_RUNTIME_ERROR = [[ diff --git a/locale/zh-tw/script.lua b/locale/zh-tw/script.lua index f9315057..ec69bea8 100644 --- a/locale/zh-tw/script.lua +++ b/locale/zh-tw/script.lua @@ -562,6 +562,8 @@ CONFIG_LOAD_ERROR = '設定檔案載入錯誤:{}' CONFIG_TYPE_ERROR = '設定檔案必須是lua或json格式:{}' +CONFIG_MODIFY_FAIL_SYNTAX_ERROR = -- TODO: need translate! +'Failed to modify settings, there are syntax errors in the settings file: {}' PLUGIN_RUNTIME_ERROR = [[ diff --git a/script/client.lua b/script/client.lua index ea80ee53..473c748b 100644 --- a/script/client.lua +++ b/script/client.lua @@ -223,20 +223,68 @@ local function getValidChanges(uri, changes) end ---@class json.patch ----@field op 'add' | 'remove' | 'replace' | 'move' | 'copy' | 'test' +---@field op 'add' | 'remove' | 'replace' ---@field path string ---@field value any +---@class json.patchInfo +---@field key string +---@field value any + +---@param cfg table +---@param rawKey string +---@return json.patchInfo +local function searchPatchInfo(cfg, rawKey) + + ---@param key string + ---@param parentKey string + ---@param parentValue table + ---@return json.patchInfo? + local function searchOnce(key, parentKey, parentValue) + if parentValue == nil then + return nil + end + if type(parentValue) ~= 'table' then + return { + key = parentKey, + value = parentValue, + } + end + if parentValue[key] then + return { + key = parentKey .. '/' .. key, + value = parentValue[key], + } + end + for pos in key:gmatch '()%.' do + local k = key:sub(1, pos - 1) + local v = parentValue[k] + local info = searchOnce(key:sub(pos + 1), parentKey .. '/' .. k, v) + if info then + return info + end + end + return nil + end + + return searchOnce(rawKey, '', cfg) + or searchOnce(rawKey:gsub('^Lua%.', ''), '', cfg) + or { + key = '/' .. rawKey, + value = nil, + } +end + ---@param cfg table ---@param change config.change ---@return json.patch? local function makeConfigPatch(cfg, change) - local value = cfg[change.key] + local info = searchPatchInfo(cfg, change.key) if change.action == 'add' then - if type(value) == 'table' and #cfg[change.key] > 0 then + if type(info.value) == 'table' and #info.value > 0 then return { op = 'add', - path = '/' .. change.key .. '/-', + path = info.key .. '/-', value = change.value, } else @@ -247,24 +295,24 @@ local function makeConfigPatch(cfg, change) }) end elseif change.action == 'set' then - if value ~= nil then + if info.value ~= nil then return { op = 'replace', - path = '/' .. change.key, + path = info.key, value = change.value, } else return { op = 'add', - path = '/' .. change.key, + path = info.key, value = change.value, } end elseif change.action == 'prop' then - if type(value) == 'table' and #value == 0 then + if type(info.value) == 'table' and #info.value == 0 then return { op = 'add', - path = '/' .. change.key .. '/' .. change.prop, + path = info.key .. '/' .. change.prop, value = change.value, } else @@ -286,13 +334,17 @@ local function editConfigJson(path, changes) if not text then return nil end - local cfg = jsonc.decode_jsonc(text) - if type(cfg) ~= 'table' then - cfg = {} + local suc, res = pcall(jsonc.decode_jsonc, text) + if not suc then + m.showMessage('Error', lang.script('CONFIG_MODIFY_FAIL_SYNTAX_ERROR', path .. res:match 'ERROR(.+)$')) + return text + end + if type(res) ~= 'table' then + res = {} end - ---@cast cfg table + ---@cast res table for _, change in ipairs(changes) do - local patch = makeConfigPatch(cfg, change) + local patch = makeConfigPatch(res, change) if patch then text = jsone.edit(text, patch, { indent = ' ' }) end diff --git a/test/tclient/tests/modify-luarc.lua b/test/tclient/tests/modify-luarc.lua index 94756847..11de446b 100644 --- a/test/tclient/tests/modify-luarc.lua +++ b/test/tclient/tests/modify-luarc.lua @@ -39,6 +39,26 @@ lclient():start(function (languageClient) ------------------------------- + util.saveFile(configPath, jsonb.beautify { + ['Lua.runtime.version'] = json.null, + }) + + provider.updateConfig() + + client.setConfig({ + { + action = 'set', + key = 'Lua.runtime.version', + value = 'LuaJIT', + } + }) + + assert(util.equal(jsonc.decode_jsonc(util.loadFile(configPath)), { + ['Lua.runtime.version'] = 'LuaJIT', + })) + + ------------------------------- + util.saveFile(configPath, jsonb.beautify(json.createEmptyObject())) provider.updateConfig() @@ -174,4 +194,134 @@ lclient():start(function (languageClient) } })) + ------------------------------- + + util.saveFile(configPath, jsonb.beautify { + ['runtime.version'] = json.null, + }) + + provider.updateConfig() + + client.setConfig({ + { + action = 'set', + key = 'Lua.runtime.version', + value = 'LuaJIT', + } + }) + + assert(util.equal(jsonc.decode_jsonc(util.loadFile(configPath)), { + ['runtime.version'] = 'LuaJIT', + })) + + ------------------------------- + + util.saveFile(configPath, jsonb.beautify { + Lua = { + runtime = { + version = json.null, + } + } + }) + + provider.updateConfig() + + client.setConfig({ + { + action = 'set', + key = 'Lua.runtime.version', + value = 'LuaJIT', + } + }) + + assert(util.equal(jsonc.decode_jsonc(util.loadFile(configPath)), { + Lua = { + runtime = { + version = 'LuaJIT', + } + } + })) + + ------------------------------- + + util.saveFile(configPath, jsonb.beautify { + runtime = { + version = json.null, + } + }) + + provider.updateConfig() + + client.setConfig({ + { + action = 'set', + key = 'Lua.runtime.version', + value = 'LuaJIT', + } + }) + + assert(util.equal(jsonc.decode_jsonc(util.loadFile(configPath)), { + runtime = { + version = 'LuaJIT', + } + })) + + ------------------------------- + + util.saveFile(configPath, jsonb.beautify { + diagnostics = { + disable = { + 'unused-local', + } + } + }) + + provider.updateConfig() + + client.setConfig({ + { + action = 'add', + key = 'Lua.diagnostics.disable', + value = 'undefined-global', + } + }) + + assert(util.equal(jsonc.decode_jsonc(util.loadFile(configPath)), { + diagnostics = { + disable = { + 'unused-local', + 'undefined-global', + } + } + })) + + ------------------------------- + + util.saveFile(configPath, jsonb.beautify { + runtime = { + special = { + import = 'require', + } + } + }) + + provider.updateConfig() + + client.setConfig({ + { + action = 'prop', + key = 'Lua.runtime.special', + prop = 'include', + value = 'require', + } + }) + + assert(util.equal(jsonc.decode_jsonc(util.loadFile(configPath)), { + runtime = { + special = { + import = 'require', + include = 'require', + } + } + })) end) |