Skip to content

Commit 2d9b061

Browse files
authored
feat(json): add abliity to remove trailing commas while stripping comments (#613)
1 parent f4faa5a commit 2d9b061

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

lua/plenary/json.lua

+17-1
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,26 @@ local M = {}
3333
-- The resulting string can then be used by `vim.fn.json_decode`
3434
--
3535
---@param jsonString string
36-
---@param options table
36+
---@param options? table
3737
--- * whitespace:
3838
--- - defaults to true
3939
--- - when true, comments will be replaced by whitespace
4040
--- - when false, comments will be stripped
41+
--- * trailing_commas:
42+
--- - defaults to false
43+
--- - when true, trailing commas will be included
44+
--- - when false, trailing commas will be removed
4145
function M.json_strip_comments(jsonString, options)
4246
options = options or {}
4347
local strip = options.whitespace == false and stripWithoutWhitespace or stripWithWhitespace
48+
local omitTrailingCommas = not options.trailing_commas
4449

4550
local insideString = false
4651
local insideComment = false
4752
local offset = 1
4853
local result = ""
4954
local skip = false
55+
local lastComma = 0
5056

5157
for i = 1, #jsonString, 1 do
5258
if skip then
@@ -89,6 +95,16 @@ function M.json_strip_comments(jsonString, options)
8995
insideComment = false
9096
result = result .. strip(jsonString, offset, i)
9197
offset = i + 1
98+
elseif omitTrailingCommas and not insideComment then
99+
if currentCharacter == "," then
100+
lastComma = i
101+
elseif (currentCharacter == "]" or currentCharacter == "}") and lastComma > 0 then
102+
result = result .. slice(jsonString, offset, lastComma - 1) .. slice(jsonString, lastComma + 1, i)
103+
offset = i + 1
104+
lastComma = 0
105+
elseif currentCharacter:match "%S" then
106+
lastComma = 0
107+
end
92108
end
93109
end
94110
end

tests/plenary/json_spec.lua

+17
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,21 @@ describe("json", function()
6767
[[{"x":"x \"sed -e \\\"s/^.\\\\{46\\\\}T//\\\" -e \\\"s/#033/\\\\x1b/g\\\"\""}]]
6868
)
6969
end)
70+
71+
it("trailing commas", function()
72+
eq(json.json_strip_comments '{"a":"b",}', '{"a":"b"}')
73+
eq(json.json_strip_comments '{"a":{"b":"c",},}', '{"a":{"b":"c"}}')
74+
eq(json.json_strip_comments '{"a":["b","c",],}', '{"a":["b","c"]}')
75+
end)
76+
77+
it("trailing commas - ignored in strings and comments", function()
78+
eq(json.json_strip_comments '{"a":"b,}"}', '{"a":"b,}"}')
79+
end)
80+
81+
it("trailing commas - left when disabled in options", function()
82+
local options = { trailing_commas = true }
83+
eq(json.json_strip_comments('{"a":"b",}', options), '{"a":"b",}')
84+
eq(json.json_strip_comments('{"a":{"b":"c",},}', options), '{"a":{"b":"c",},}')
85+
eq(json.json_strip_comments('{"a":["b","c",],}', options), '{"a":["b","c",],}')
86+
end)
7087
end)

0 commit comments

Comments
 (0)