aboutsummaryrefslogtreecommitdiffstats
path: root/lua/pi/php/gateway.lua
blob: 83c95e994508df6586a1f0d046e3b61f56ed5bd0 (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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
local pickers = require "telescope.pickers"
local finders = require "telescope.finders"
local conf = require("telescope.config").values
local action_state = require "telescope.actions.state"
local action_set = require "telescope.actions.set"
local actions = require "telescope.actions"
local get_node_text = vim.treesitter.get_node_text

local gateway = {}

local get_definition_buffer = function(type)
  local uri = vim.uri_from_fname(vim.fn.getcwd() .. "/config/graphql/_" .. type .. ".yaml")
  local buff = vim.uri_to_bufnr(uri)
  vim.fn.bufload(buff)

  return buff
end

local get_all_definitions = function()
  local mutations_definitions = gateway.get_graphql_definitions(get_definition_buffer "mutation")
  local queries_definitions = gateway.get_graphql_definitions(get_definition_buffer "query")
  for _, definition in ipairs(queries_definitions) do
    table.insert(mutations_definitions, definition)
  end

  return mutations_definitions
end

-- "'@=mutation(\"App\\\\GraphQL\\\\Mutations\\\\Mutation::action\", ...)'",
local open_resolver = function(resolver)
  -- need to parse to get this values
  local args = string.match(resolver, "'@=mutation%((.+)%)'")
  if args == nil then
    args = string.match(resolver, "'@=query%((.+)%)'")
  end
  if args == nil then
    return
  end

  local args_tbl = vim.split(args, ", ")
  local fqn = string.match(args_tbl[1], '"(.+)"')
  fqn = string.gsub(fqn, "\\\\", "\\")
  -- P(fqn)

  require("pi.php.lsp").find(fqn, "phpactor")
end

--- @param bufnr integer Buff id
gateway.get_graphql_definitions = function(bufnr)
  vim.treesitter.query.set(
    "yaml",
    "GraphQL_endpoints",
    [[
    (document (block_node (block_mapping (block_mapping_pair
        value: (block_node (block_mapping (block_mapping_pair
            value: (block_node (block_mapping (block_mapping_pair
                value: (block_node (block_mapping (block_mapping_pair
                    key: (flow_node) @mutation
                    value: (block_node (block_mapping (block_mapping_pair
                         key: (flow_node) @resolve (#eq? @resolve "resolve")
                         value: (flow_node) @resolver
                     )))
                )))
            )))
        )))
    ))))
        ]]
  )

  local query = vim.treesitter.query.get("yaml", "GraphQL_endpoints")

  local elements = {}

  local parsers = require "nvim-treesitter.parsers"
  local parser = parsers.get_parser(bufnr)
  local tree = parser:parse()[1]

  for id, node in query:iter_captures(tree:root(), bufnr) do
    if query.captures[id] == "mutation" then
      table.insert(elements, {
        value = get_node_text(node, bufnr),
        lnum = node:start() + 1,
        buffer = bufnr,
      })
    elseif query.captures[id] == "resolver" then
      elements[#elements].resolver = get_node_text(node, bufnr)
    end
  end

  return elements
end

--- gets the graphql function defined on a given buffer
--- @param opts table: options to pass to the picker
gateway.graphql_definitions = function(opts)
  opts = opts or {}
  pickers
    .new(opts, {
      promt_title = "Queries",
      finder = finders.new_table {
        results = get_all_definitions(),
        entry_maker = function(entry)
          -- buffer = 43,
          -- lnum = 82,
          -- resolver = "'@=mutation(\"App\\\\GraphQL\\\\Mutation\\\\Mutation::action\", ...)'",
          -- value = "deleteVehicleImage"
          return {
            value = entry,
            display = entry.value,
            ordinal = entry.value,
            path = vim.api.nvim_buf_get_name(entry.buffer),
            lnum = entry.lnum,
            resolver = entry.resolver,
          }
        end,
      },
      sorter = conf.generic_sorter(opts),
      previewer = conf.grep_previewer(opts),
      attach_mappings = function(prompt_bufnr, map)
        action_set.select:enhance {
          post = function()
            local selection = action_state.get_selected_entry()
            vim.api.nvim_win_set_cursor(0, { selection.lnum, 0 })
          end,
        }
        map("i", "<c-o>", function()
          actions.close(prompt_bufnr)
          local selection = action_state.get_selected_entry()
          open_resolver(selection.resolver)
        end)
        return true
      end,
    })
    :find()
end

return gateway