local capabilities = require("cmake-explorer.capabilities") local Path = require("plenary.path") local Scandir = require("plenary.scandir") local notif = require("cmake-explorer.notification") local query_path_suffix = { ".cmake", "api", "v1", "query", "client-cmake-explorer", "query.json" } local reply_dir_suffix = { ".cmake", "api", "v1", "reply" } local FileApi = {} FileApi.__index = FileApi function FileApi:new(opts) if not capabilities.has_fileapi() then notif.notify("No fileapi files", vim.log.levels.ERROR) return end local path if type(opts) == "string" then path = opts end local obj = { path = Path:new(path):absolute(), index = nil, cmakefiles = nil, codemodel = nil, targets = nil, } Path:new(path):mkdir({ parents = true }) setmetatable(obj, FileApi) return obj end function FileApi:create() local query = Path:new(self.path, unpack(query_path_suffix)) if not query:exists() then if not query:touch({ parents = true }) then notif.notify("Cannot create query file", vim.log.levels.ERROR) return end query:write(vim.json.encode(capabilities.json.fileApi), "w") end Path:new(self.path, unpack(reply_dir_suffix)):mkdir({ parents = true }) return true end function FileApi:read_reply() if not self:reply_exists() then notif.notify("No reply directory", vim.log.levels.ERROR) return end local reply_dir = Path:new(self.path, unpack(reply_dir_suffix)) local index = Scandir.scan_dir(tostring(reply_dir), { search_pattern = "index*" }) if #index == 0 then notif.notify("No files in reply", vim.log.levels.ERROR) return end self.index = vim.json.decode(Path:new(index[1]):read()) for _, object in ipairs(self.index.objects) do if object.kind == "codemodel" then self.codemodel = vim.json.decode((reply_dir / object.jsonFile):read()) self.targets = {} for _, target in ipairs(self.codemodel.configurations[1].targets) do table.insert(self.targets, vim.json.decode((reply_dir / target.jsonFile):read())) end elseif object.kind == "cmakeFiles" then self.cmakefiles = vim.json.decode(Path:new(reply_dir / object.jsonFile):read()) end end return true end function FileApi:query_exists() return Path:new(self.path, unpack(query_path_suffix)):exists() end function FileApi:reply_exists() local reply_dir = Path:new(self.path, unpack(reply_dir_suffix)) if not reply_dir:exists() then return end return true end function FileApi:exists() return self:query_exists() and self:reply_exists() end function FileApi.is_fileapi(other) return getmetatable(other) == FileApi end return FileApi