aboutsummaryrefslogtreecommitdiff
path: root/lua/cmake-explorer/file_api.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua/cmake-explorer/file_api.lua')
-rw-r--r--lua/cmake-explorer/file_api.lua93
1 files changed, 93 insertions, 0 deletions
diff --git a/lua/cmake-explorer/file_api.lua b/lua/cmake-explorer/file_api.lua
new file mode 100644
index 0000000..cd83be4
--- /dev/null
+++ b/lua/cmake-explorer/file_api.lua
@@ -0,0 +1,93 @@
+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