aboutsummaryrefslogtreecommitdiff
path: root/lua/cmake-explorer/file_api.lua
blob: cd83be4c6b21530a5daf71f02ed0ce25396a290c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
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