Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion lua/plenary/json.lua
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,26 @@ local M = {}
-- The resulting string can then be used by `vim.fn.json_decode`
--
---@param jsonString string
---@param options table
---@param options? table
--- * whitespace:
--- - defaults to true
--- - when true, comments will be replaced by whitespace
--- - when false, comments will be stripped
--- * trailing_commas:
--- - defaults to false
--- - when true, trailing commas will be included
--- - when false, trailing commas will be removed
function M.json_strip_comments(jsonString, options)
options = options or {}
local strip = options.whitespace == false and stripWithoutWhitespace or stripWithWhitespace
local omitTrailingCommas = not options.trailing_commas

local insideString = false
local insideComment = false
local offset = 1
local result = ""
local skip = false
local lastComma = 0

for i = 1, #jsonString, 1 do
if skip then
Expand Down Expand Up @@ -89,6 +95,16 @@ function M.json_strip_comments(jsonString, options)
insideComment = false
result = result .. strip(jsonString, offset, i)
offset = i + 1
elseif omitTrailingCommas and not insideComment then
if currentCharacter == "," then
lastComma = i
elseif (currentCharacter == "]" or currentCharacter == "}") and lastComma > 0 then
result = result .. slice(jsonString, offset, lastComma - 1) .. slice(jsonString, lastComma + 1, i)
offset = i + 1
lastComma = 0
elseif currentCharacter:match "%S" then
lastComma = 0
end
end
end
end
Expand Down
17 changes: 17 additions & 0 deletions tests/plenary/json_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,21 @@ describe("json", function()
[[{"x":"x \"sed -e \\\"s/^.\\\\{46\\\\}T//\\\" -e \\\"s/#033/\\\\x1b/g\\\"\""}]]
)
end)

it("trailing commas", function()
eq(json.json_strip_comments '{"a":"b",}', '{"a":"b"}')
eq(json.json_strip_comments '{"a":{"b":"c",},}', '{"a":{"b":"c"}}')
eq(json.json_strip_comments '{"a":["b","c",],}', '{"a":["b","c"]}')
end)

it("trailing commas - ignored in strings and comments", function()
eq(json.json_strip_comments '{"a":"b,}"}', '{"a":"b,}"}')
end)

it("trailing commas - left when disabled in options", function()
local options = { trailing_commas = true }
eq(json.json_strip_comments('{"a":"b",}', options), '{"a":"b",}')
eq(json.json_strip_comments('{"a":{"b":"c",},}', options), '{"a":{"b":"c",},}')
eq(json.json_strip_comments('{"a":["b","c",],}', options), '{"a":["b","c",],}')
end)
end)