125 lines
3.4 KiB
Lua
125 lines
3.4 KiB
Lua
-- local ts_utils = require 'nvim-treesitter.ts_utils'
|
|
local utils = require("go.utils")
|
|
local log = utils.log
|
|
local pkg = require("go.package")
|
|
local fn = vim.fn
|
|
|
|
local guru = "guru"
|
|
local vfn = vim.fn
|
|
|
|
-- guru_cmd returns a dict that contains the command to execute guru. args
|
|
-- is dict with following options:
|
|
-- mode : guru mode, such as 'implements'
|
|
-- format : output format, either 'plain' or 'json'
|
|
-- needs_scope : if 1, adds the current package to the scope
|
|
-- selected : if 1, means it's a range of selection, otherwise it picks up the
|
|
-- offset under the cursor
|
|
-- example output:
|
|
-- {'cmd' : ['guru', '-json', 'implements', 'demo/demo.go:#66']}
|
|
local guru_cmd = function(args)
|
|
local mode = args.mode
|
|
local format = args.format
|
|
local selected = args.selected
|
|
local postype = vim.fn.get(args, "postype", "cursor")
|
|
local need_scope = args.needs_scope
|
|
local result = {}
|
|
local build_tags = require("go.gotest").get_build_tags()
|
|
require("go.install").install(guru)
|
|
local cmd = { guru }
|
|
if build_tags then
|
|
table.insert(cmd, build_tags)
|
|
end
|
|
|
|
if vim.o.modified then
|
|
table.insert(cmd, "-modified")
|
|
end
|
|
if format == "json" then
|
|
table.insert(cmd, "-json")
|
|
end
|
|
|
|
local fname = vfn.expand("%:p") -- %:p:h ? %:p
|
|
-- local fpath = vfn.expand("%:p:h") -- %:p:h ? %:p
|
|
|
|
if need_scope then
|
|
local scope = pkg.pkg_from_path()
|
|
log(scope)
|
|
if scope then
|
|
table.insert(cmd, "-scope")
|
|
table.insert(cmd, fn.join(scope, ","))
|
|
end
|
|
end
|
|
local pos
|
|
if postype == "balloon" then
|
|
local byte_offset = utils.offset(vim.v.beval_lnum, vim.v.beval_col)
|
|
pos = string.format("#%s", byte_offset)
|
|
else
|
|
if selected ~= -1 then -- visual mode
|
|
local pos1 = utils.offset(fn.line("'<"), fn.col("'<"))
|
|
local pos2 = utils.offset(fn.line("'>"), fn.col("'>"))
|
|
pos = string.format("#%s,#%s", pos1, pos2)
|
|
else
|
|
pos = string.format("#%s", vfn.wordcount().cursor_bytes)
|
|
end
|
|
end
|
|
|
|
local filename = fn.fnamemodify(fn.expand("%"), ":p:gs?\\?/?") .. ":" .. pos
|
|
table.insert(cmd, mode)
|
|
table.insert(cmd, filename)
|
|
log(cmd)
|
|
print(vim.inspect(cmd))
|
|
|
|
vfn.jobstart(cmd, {
|
|
on_exit = function(status, data, stderr)
|
|
log(status, data)
|
|
end,
|
|
on_stderr = function(e, data)
|
|
log(e, data)
|
|
end,
|
|
on_stdout = function(_, data, _)
|
|
data = utils.handle_job_data(data)
|
|
if not data then
|
|
return
|
|
end
|
|
print(data)
|
|
log(data)
|
|
local res = data
|
|
if format == "json" then
|
|
local re = vim.json.decode(data)
|
|
if re.errors ~= nil or re.lines == nil or re["start"] == nil or re["start"] == 0 then
|
|
vim.notify("failed to run guru" .. vim.inspect(re), vim.lsp.log_levels.ERROR)
|
|
end
|
|
end
|
|
if #res > 0 then
|
|
vim.fn.setqflist({}, " ", {
|
|
title = cmd,
|
|
lines = res,
|
|
efm = [[%f:%l.%c-%[%^:]%#:\ %m,%f:%l:%c:\ %m]],
|
|
})
|
|
end
|
|
|
|
vim.notify("guru " .. mode, vim.lsp.log_levels.INFO)
|
|
end,
|
|
})
|
|
end
|
|
|
|
local function callstack(selected)
|
|
selected = selected or -1
|
|
guru_cmd({
|
|
mode = "callstack",
|
|
format = "plain",
|
|
needs_scope = 1,
|
|
selected = selected,
|
|
})
|
|
end
|
|
|
|
local function channel_peers(selected)
|
|
selected = selected or -1
|
|
guru_cmd({
|
|
mode = "peers",
|
|
format = "plain",
|
|
needs_scope = 1,
|
|
selected = selected,
|
|
})
|
|
end
|
|
return { guru_cmd = guru_cmd, callstack = callstack, channel_peers = channel_peers }
|