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