@@ -223,20 +223,68 @@ local function getValidChanges(uri, changes)
223
223
end
224
224
225
225
--- @class json.patch
226
- --- @field op ' add' | ' remove' | ' replace' | ' move ' | ' copy ' | ' test '
226
+ --- @field op ' add' | ' remove' | ' replace'
227
227
--- @field path string
228
228
--- @field value any
229
229
230
+ --- @class json.patchInfo
231
+ --- @field key string
232
+ --- @field value any
233
+
234
+ --- @param cfg table
235
+ --- @param rawKey string
236
+ --- @return json.patchInfo
237
+ local function searchPatchInfo (cfg , rawKey )
238
+
239
+ --- @param key string
240
+ --- @param parentKey string
241
+ --- @param parentValue table
242
+ --- @return json.patchInfo ?
243
+ local function searchOnce (key , parentKey , parentValue )
244
+ if parentValue == nil then
245
+ return nil
246
+ end
247
+ if type (parentValue ) ~= ' table' then
248
+ return {
249
+ key = parentKey ,
250
+ value = parentValue ,
251
+ }
252
+ end
253
+ if parentValue [key ] then
254
+ return {
255
+ key = parentKey .. ' /' .. key ,
256
+ value = parentValue [key ],
257
+ }
258
+ end
259
+ for pos in key :gmatch ' ()%.' do
260
+ local k = key :sub (1 , pos - 1 )
261
+ local v = parentValue [k ]
262
+ local info = searchOnce (key :sub (pos + 1 ), parentKey .. ' /' .. k , v )
263
+ if info then
264
+ return info
265
+ end
266
+ end
267
+ return nil
268
+ end
269
+
270
+ return searchOnce (rawKey , ' ' , cfg )
271
+ or searchOnce (rawKey :gsub (' ^Lua%.' , ' ' ), ' ' , cfg )
272
+ or {
273
+ key = ' /' .. rawKey ,
274
+ value = nil ,
275
+ }
276
+ end
277
+
230
278
--- @param cfg table
231
279
--- @param change config.change
232
280
--- @return json.patch ?
233
281
local function makeConfigPatch (cfg , change )
234
- local value = cfg [ change .key ]
282
+ local info = searchPatchInfo ( cfg , change .key )
235
283
if change .action == ' add' then
236
- if type (value ) == ' table' and # cfg [ change . key ] > 0 then
284
+ if type (info . value ) == ' table' and # info . value > 0 then
237
285
return {
238
286
op = ' add' ,
239
- path = ' / ' .. change .key .. ' /-' ,
287
+ path = info .key .. ' /-' ,
240
288
value = change .value ,
241
289
}
242
290
else
@@ -247,24 +295,24 @@ local function makeConfigPatch(cfg, change)
247
295
})
248
296
end
249
297
elseif change .action == ' set' then
250
- if value ~= nil then
298
+ if info . value ~= nil then
251
299
return {
252
300
op = ' replace' ,
253
- path = ' / ' .. change .key ,
301
+ path = info .key ,
254
302
value = change .value ,
255
303
}
256
304
else
257
305
return {
258
306
op = ' add' ,
259
- path = ' / ' .. change .key ,
307
+ path = info .key ,
260
308
value = change .value ,
261
309
}
262
310
end
263
311
elseif change .action == ' prop' then
264
- if type (value ) == ' table' and # value == 0 then
312
+ if type (info . value ) == ' table' and # info . value == 0 then
265
313
return {
266
314
op = ' add' ,
267
- path = ' / ' .. change .key .. ' /' .. change .prop ,
315
+ path = info .key .. ' /' .. change .prop ,
268
316
value = change .value ,
269
317
}
270
318
else
@@ -286,13 +334,17 @@ local function editConfigJson(path, changes)
286
334
if not text then
287
335
return nil
288
336
end
289
- local cfg = jsonc .decode_jsonc (text )
290
- if type (cfg ) ~= ' table' then
291
- cfg = {}
337
+ local suc , res = pcall (jsonc .decode_jsonc , text )
338
+ if not suc then
339
+ m .showMessage (' Error' , lang .script (' CONFIG_MODIFY_FAIL_SYNTAX_ERROR' , path .. res :match ' ERROR(.+)$' ))
340
+ return text
341
+ end
342
+ if type (res ) ~= ' table' then
343
+ res = {}
292
344
end
293
- --- @cast cfg table
345
+ --- @cast res table
294
346
for _ , change in ipairs (changes ) do
295
- local patch = makeConfigPatch (cfg , change )
347
+ local patch = makeConfigPatch (res , change )
296
348
if patch then
297
349
text = jsone .edit (text , patch , { indent = ' ' })
298
350
end
0 commit comments