Skip to content

Commit 3beee51

Browse files
mous16lceWolf
authored andcommitted
fix: recursive presets includes discovery
1 parent 47c10ee commit 3beee51

1 file changed

Lines changed: 31 additions & 15 deletions

File tree

lua/cmake-tools/presets.lua

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,30 @@ end
1515

1616
-- Decodes a Cmake[User]Presets.json and its "includes", if any
1717
-- CMakeUserPresets.json implicitly includes CMakePresets.json if it exists
18-
local function decode(file)
19-
local data = vim.fn.json_decode(vim.fn.readfile(file))
18+
local function decode(file, visited)
19+
visited = visited or {}
20+
local abs_file_path = vim.fn.fnamemodify(file, ":p")
21+
22+
if visited[abs_file_path] then
23+
return {}
24+
end
25+
26+
local file_path = Path:new(abs_file_path)
27+
if not file_path:exists() or file_path:is_dir() then
28+
return {} -- Do not error on missing include
29+
end
30+
31+
visited[abs_file_path] = true
32+
33+
local data = vim.fn.json_decode(file_path:read())
2034
if not data then
21-
error(string.format("Could not parse %s", file))
35+
error(string.format("Could not parse %s", abs_file_path))
2236
end
23-
local includes = data["include"] and data["include"] or {}
24-
local includes_is_empty = next(includes) == nil
25-
local isUserPreset = string.find(file:lower(), "user")
26-
local parentDir = vim.fs.dirname(file)
37+
local includes = data.include or {}
38+
local includes_is_empty = #includes == 0
39+
local isUserPreset = string.find(abs_file_path:lower(), "user")
40+
local parentDir = vim.fs.dirname(abs_file_path)
41+
2742
if includes_is_empty and isUserPreset then
2843
local preset = "CMakePresets.json"
2944
local presetKebapCase = "cmake-presets.json"
@@ -37,20 +52,20 @@ local function decode(file)
3752
end
3853
end
3954

40-
if includes_is_empty then
55+
if #includes == 0 then
4156
return data
4257
end
4358

4459
for _, f in ipairs(includes) do
45-
local f_read_data = nil
46-
local f_path = Path.new(f)
60+
local f_path_str
61+
local f_path = Path:new(f)
4762
if f_path:is_absolute() then
48-
f_read_data = f_path:read()
63+
f_path_str = f
4964
else
50-
f_read_data = (Path.new(parentDir) / f):read()
65+
f_path_str = tostring(Path:new(parentDir) / f)
5166
end
5267

53-
local fdata = vim.fn.json_decode(f_read_data)
68+
local fdata = decode(f_path_str, visited)
5469
local thisFilePresetKeys = vim.tbl_filter(function(key)
5570
if string.find(key, "Presets") then
5671
return true
@@ -97,10 +112,11 @@ function Presets:parse(cwd)
97112

98113
local userPresetFile, presetFile = self.find_preset_files(cwd)
99114

100-
local data = decode(userPresetFile)
115+
local visited = {}
116+
local data = decode(userPresetFile, visited)
101117

102118
if presetFile then
103-
local presetData = decode(presetFile)
119+
local presetData = decode(presetFile, visited)
104120
if presetData then
105121
data = merge_presets(data, presetData)
106122
end

0 commit comments

Comments
 (0)