-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinit.lua
More file actions
187 lines (160 loc) · 4.96 KB
/
init.lua
File metadata and controls
187 lines (160 loc) · 4.96 KB
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
local ms, api, lsp = vim.lsp.protocol.Methods, vim.api, vim.lsp
local M = {}
local server = require('visualizer.server')
local utils = require('visualizer.utils')
local INCOMING, OUTGOING, FULL, GALAXY = 1, 2, 3, 4
local function hierarchy_request(client, bufnr, win, mode)
local cursor_pos = api.nvim_win_get_cursor(win)
local root = {
detail = vim.fn.expand('<cword>'),
line = cursor_pos[1],
column = cursor_pos[2] + 1,
file = api.nvim_buf_get_name(bufnr),
}
local params = vim.lsp.util.make_position_params(win, client.offset_encoding)
client:request(ms.textDocument_prepareCallHierarchy, params, function(err, result)
if err or not result or next(result) == nil then
vim.notify('No call hierarchy available', vim.log.levels.WARN)
return
end
local hierarchy_item = result[1]
local chain_data = { nodes = {}, edges = {}, mode = mode }
local root_node = utils.create_root_node(root, hierarchy_item)
table.insert(chain_data.nodes, root_node)
local methods = {
{ ms.callHierarchy_incomingCalls },
{ ms.callHierarchy_outgoingCalls },
{ ms.callHierarchy_incomingCalls, ms.callHierarchy_outgoingCalls },
}
local add_method = { utils.add_incoming_calls, utils.add_outgoing_calls }
local co
co = coroutine.create(function()
local results = {}
for i, method in ipairs(methods[mode]) do
---@diagnostic disable-next-line: redefined-local
client:request(method, { item = hierarchy_item }, function(err, res)
local data = {}
if not err and res and not vim.tbl_isempty(res) then
data.result = res
else
data.err = err
end
coroutine.resume(co, data)
end, bufnr)
local data = coroutine.yield(co)
if data.err then
vim.schedule(function()
vim.notify(data.err.message)
end)
else
results[i] = data.result
end
if i == #methods[mode] then
for idx, item in pairs(results) do
add_method[idx](chain_data, item, root_node.id)
end
local final_data = utils.finalize_data(chain_data)
server.send_data(final_data)
vim.schedule(function()
server.open()
end)
end
end
end)
coroutine.resume(co)
end, bufnr)
end
local function galaxy_request(client, bufnr)
client:request(ms.workspace_symbol, { query = '' }, function(err, result)
if err then
vim.notify('Failed to get workspace symbols: ' .. err.message, vim.log.levels.ERROR)
return
end
if not result or #result == 0 then
vim.notify('No workspace symbols found', vim.log.levels.WARN)
return
end
vim.notify(string.format('Found %d symbols, generating galaxy...', #result), vim.log.levels.INFO)
local galaxy_data = utils.create_galaxy(result)
server.send_data(galaxy_data)
vim.schedule(function()
server.open()
end)
end, bufnr)
end
local function hierarchy(mode)
if mode == GALAXY then
local bufnr = api.nvim_get_current_buf()
local clients = lsp.get_clients({ bufnr = bufnr, method = ms.workspace_symbol })
if not next(clients) then
vim.notify('No LSP client supports workspace symbols', vim.log.levels.WARN)
return
end
if #clients == 1 then
galaxy_request(clients[1], bufnr)
return
end
local clients_map = {}
for _, client in ipairs(clients) do
clients_map[client.name] = client
end
vim.ui.select(vim.tbl_keys(clients_map), {
prompt = 'Select a client for galaxy view:',
}, function(choice)
if not clients_map[choice] then
return
end
galaxy_request(clients_map[choice], bufnr)
end)
return
end
local prepare_method = ms.textDocument_prepareCallHierarchy
local bufnr = api.nvim_get_current_buf()
local clients = lsp.get_clients({ bufnr = bufnr, method = prepare_method })
if not next(clients) then
vim.notify(lsp._unsupported_method(prepare_method), vim.log.levels.WARN)
return
end
local win = api.nvim_get_current_win()
if #clients == 1 then
hierarchy_request(clients[1], bufnr, win, mode)
return
end
local clients_map = {}
for _, client in ipairs(clients) do
clients_map[client.name] = client
end
vim.ui.select(vim.tbl_keys(clients_map), {
prompt = 'Select a client:',
}, function(choice)
if not clients_map[choice] then
return
end
hierarchy_request(clients_map[choice], bufnr, win, mode)
end)
end
function M.incoming()
server.start_server()
vim.schedule(function()
hierarchy(INCOMING)
end)
end
function M.outgoing()
server.start_server()
vim.schedule(function()
hierarchy(OUTGOING)
end)
end
function M.full()
server.start_server()
vim.schedule(function()
hierarchy(FULL)
end)
end
function M.workspace_symbol()
server.start_server(require('visualizer.symbol').symbol_html)
vim.schedule(function()
hierarchy(GALAXY)
end)
end
return M