aboutsummaryrefslogtreecommitdiffstats
path: root/lua/config/composer.lua
blob: 24054168645f8a0ec1487a254e89f05210c8c4bf (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
94
95
96
97
98
99
100
101
102
103
104
vim.treesitter.query.set(
  "json",
  "composer_dependencies",
  [[
    (pair
        key: (string
            (string_content) @key (#match? @key "require|require-dev")
        )
        value: (object
            (pair
                key: (string (string_content) @depen)
            )
        )
    )
  ]]
)
local group = vim.api.nvim_create_augroup("composer-info", {})
vim.api.nvim_create_autocmd({ "BufEnter", "BufWritePost" }, {
  pattern = "composer.json",
  group = group,
  callback = function(event)
    local parser = vim.treesitter.get_parser(event.buf, "json")
    local tree = parser:parse()[1]
    if tree == nil then
      return
    end
    local query = vim.treesitter.query.get("json", "composer_dependencies")
    if not query then
      return
    end

    local dependencies = {}

    for id, node in query:iter_captures(tree:root(), event.buf) do
      if query.captures[id] == "depen" then
        table.insert(dependencies, {
          name = vim.treesitter.get_node_text(node, event.buf),
          line = node:start(),
        })
      end
    end

    if #dependencies == 0 then
      return
    end

    local ns = vim.api.nvim_create_namespace("composer-deps")
    vim.api.nvim_buf_clear_namespace(event.buf, ns, 0, -1)

    vim.system(
      { "composer", "info", "-f", "json" },
      {},
      vim.schedule_wrap(function(out)
        if out.code ~= 0 then
          return
        end

        local data = vim.json.decode(out.stdout, {})
        if type(data.installed) ~= "table" then
          return
        end

        for _, dep in ipairs(dependencies) do
          local info = vim.iter(data.installed):find(function(inst)
            return dep.name == inst.name
          end)
          if info then
            vim.api.nvim_buf_set_extmark(event.buf, ns, dep.line, 0, {
              virt_text = { { string.format('<- %s', info.version), "comment" } },
              virt_text_pos = "eol",
            })
          end
        end
      end)
    )
    vim.system(
      { "composer", "outdated", "-f", "json" },
      {},
      vim.schedule_wrap(function(out)
        if out.code ~= 0 then
          return
        end

        local data = vim.json.decode(out.stdout, {})
        if type(data.installed) ~= "table" then
          return
        end

        for _, dep in ipairs(dependencies) do
          local info = vim.iter(data.installed):find(function(inst)
            return dep.name == inst.name
          end)
          if info then
            vim.api.nvim_buf_set_extmark(event.buf, ns, dep.line - 1, 0, {
              virt_text = { { string.format('^ %s (new version)', info.latest), "error" } },
              virt_text_pos = "eol",
            })
          end
        end
      end)
    )
  end,
})