ccls call hierarchy

pull/25/head
ray-x 3 years ago
parent 7514fa9f70
commit 298c4659da

@ -0,0 +1,101 @@
local gui = require "navigator.gui"
local util = require "navigator.util"
local log = util.log
local partial = util.partial
local lsphelper = require "navigator.lspwrapper"
local cwd = vim.fn.getcwd(0)
local M = {}
local function call_hierarchy_handler(direction, err, api, result, _, _, error_message)
log('call_hierarchy')
log('call_hierarchy', direction, err, result)
assert(#vim.lsp.buf_get_clients() > 0, "Must have a client running to use lsp_tags")
if err ~= nil then
log(api, "dir", direction, "result", result, "err", err)
print("ERROR: " .. error_message)
return
end
-- local funcs = vim.lsp.util.locations_to_items(result)
-- log(funcs)
local items = {}
for _, call_hierarchy in pairs(result) do
local kind = ''
range = call_hierarchy.range
local filename = assert(vim.uri_to_fname(call_hierarchy.uri))
local display_filename = filename:gsub(cwd .. "/", "./", 1)
local bufnr = vim.uri_to_bufnr(call_hierarchy.uri)
local row = range.start.line
local line = (vim.api.nvim_buf_get_lines(bufnr, row, row + 1, false) or {""})[1]
fn = ""
if line ~= nil then
fn = line:sub(range.start.character, range['end'].character + 1)
end
table.insert(items, {
uri = call_hierarchy.uri,
filename = filename,
-- display_filename = filename:gsub(cwd .. "/", "./", 1),
display_filename = display_filename,
text = kind .. fn,
range = range,
lnum = range.start.line + 1,
col = range.start.character
})
end
return items
end
local call_hierarchy_handler_from = partial(call_hierarchy_handler, "from")
local call_hierarchy_handler_to = partial(call_hierarchy_handler, "to")
local function incoming_calls_handler(bang, err, method, result, client_id, bufnr)
assert(#vim.lsp.buf_get_clients() > 0, "Must have a client running to use lsp_tags")
local results = call_hierarchy_handler_from(err, method, result, client_id, bufnr,
"Incoming calls not found")
local ft = vim.api.nvim_buf_get_option(bufnr, "ft")
gui.new_list_view({items = results, ft = ft, api = ''})
end
local function outgoing_calls_handler(bang, err, method, result, client_id, bufnr)
local results = call_hierarchy_handler_to(err, method, result, client_id, bufnr,
"Outgoing calls not found")
local ft = vim.api.nvim_buf_get_option(bufnr, "ft")
gui.new_list_view({items = results, ft = ft, api = ''})
-- fzf_locations(bang, "", "Outgoing Calls", results, false)
end
function M.incoming_calls(bang, opts)
assert(#vim.lsp.buf_get_clients() > 0, "Must have a client running to use lsp_tags")
-- if not lsphelper.check_capabilities("call_hierarchy") then
-- return
-- end
local params = vim.lsp.util.make_position_params()
-- params['hierarchy'] = true
params['levels'] = 2
params['callee'] = false
-- params['callee'] = true
log(params)
log(opts)
lsphelper.call_sync("$ccls/call", params, opts, partial(incoming_calls_handler, bang))
end
function M.outgoing_calls(bang, opts)
assert(#vim.lsp.buf_get_clients() > 0, "Must have a client running to use lsp_tags")
local params = vim.lsp.util.make_position_params()
params['levels'] = 2
params['callee'] = true
log(params)
lsphelper.call_sync("$ccls/call", params, opts, partial(outgoing_calls_handler, bang))
end
M.incoming_calls_call = partial(M.incoming_calls, 0)
M.outgoing_calls_call = partial(M.outgoing_calls, 0)
M.incoming_calls_handler = partial(incoming_calls_handler, 0)
M.outgoing_calls_handler = partial(outgoing_calls_handler, 0)
return M

@ -42,7 +42,9 @@ local diag_hdlr = function(err, method, result, client_id, br, config)
head = _NgConfigValues.icons.diagnostic_head_severity_3 head = _NgConfigValues.icons.diagnostic_head_severity_3
end end
local bufnr = vim.uri_to_bufnr(uri) local bufnr = vim.uri_to_bufnr(uri)
vim.fn.bufload(bufnr) if not vim.api.nvim_buf_is_loaded(bufnr) then
vim.fn.bufload(bufnr)
end
local pos = v.range.start local pos = v.range.start
local row = pos.line local row = pos.line
local line = (vim.api.nvim_buf_get_lines(bufnr, row, row + 1, false) or {""})[1] local line = (vim.api.nvim_buf_get_lines(bufnr, row, row + 1, false) or {""})[1]
@ -64,10 +66,7 @@ M.diagnostic_handler = vim.lsp.with(diag_hdlr, {
-- Enable underline, use default values -- Enable underline, use default values
underline = true, underline = true,
-- Enable virtual text, override spacing to 0 -- Enable virtual text, override spacing to 0
virtual_text = { virtual_text = {spacing = 0, prefix = _NgConfigValues.icons.diagnostic_virtual_text},
spacing = 0,
prefix = _NgConfigValues.icons.diagnostic_virtual_text
},
-- Use a function to dynamically turn signs off -- Use a function to dynamically turn signs off
-- and on, using buffer local variables -- and on, using buffer local variables
signs = true, signs = true,
@ -101,7 +100,8 @@ M.show_diagnostic = function()
if #display_items > 0 then if #display_items > 0 then
gui.new_list_view({ gui.new_list_view({
items = display_items, items = display_items,
api = _NgConfigValues.icons.diagnostic_file .. _NgConfigValues.icons.diagnostic_head .. " Diagnostic ", api = _NgConfigValues.icons.diagnostic_file .. _NgConfigValues.icons.diagnostic_head
.. " Diagnostic ",
enable_preview_edit = true enable_preview_edit = true
}) })
end end

@ -153,29 +153,8 @@ function M.new_list_view(opts)
if prompt then if prompt then
offset_y = offset_y + 1 -- need to check this out offset_y = offset_y + 1 -- need to check this out
end end
local idx = require"guihua.util".fzy_idx
local function idx(data_list, pos)
-- first check if fzy is set
local fzy_on = false
for _, value in ipairs(data_list) do
if value.fzy ~= nil then
fzy_on = true
break
end
end
if fzy_on == true then
local i = 1
for _, value in ipairs(data_list) do
if value.fzy ~= nil then
if i == pos then
return value
end
i = i + 1
end
end
end
return data[pos]
end
return ListView:new({ return ListView:new({
loc = loc, loc = loc,
prompt = prompt, prompt = prompt,

@ -7,8 +7,7 @@ local cwd = vim.fn.getcwd(0)
local M = {} local M = {}
local function call_hierarchy_handler(direction, err, _, result, _, _, error_message) local function call_hierarchy_handler(direction, err, _, result, _, _, error_message)
-- log('call_hierarchy') log('call_hierarchy')
assert(#vim.lsp.buf_get_clients() > 0, "Must have a client running to use lsp_tags") assert(#vim.lsp.buf_get_clients() > 0, "Must have a client running to use lsp_tags")
if err ~= nil then if err ~= nil then
log("dir", direction, "result", result, "err", err) log("dir", direction, "result", result, "err", err)
@ -17,6 +16,7 @@ local function call_hierarchy_handler(direction, err, _, result, _, _, error_mes
end end
local items = {} local items = {}
for _, call_hierarchy_call in pairs(result) do for _, call_hierarchy_call in pairs(result) do
local call_hierarchy_item = call_hierarchy_call[direction] local call_hierarchy_item = call_hierarchy_call[direction]
local kind = '' local kind = ''
@ -69,7 +69,8 @@ function M.incoming_calls(bang, opts)
end end
local params = vim.lsp.util.make_position_params() local params = vim.lsp.util.make_position_params()
util.call_sync("callHierarchy/incomingCalls", params, opts, partial(incoming_calls_handler, bang)) lsphelper.call_sync("callHierarchy/incomingCalls", params, opts,
partial(incoming_calls_handler, bang))
end end
function M.outgoing_calls(bang, opts) function M.outgoing_calls(bang, opts)
@ -79,7 +80,8 @@ function M.outgoing_calls(bang, opts)
end end
local params = vim.lsp.util.make_position_params() local params = vim.lsp.util.make_position_params()
util.call_sync("callHierarchy/outgoingCalls", params, opts, partial(outgoing_calls_handler, bang)) lsphelper.call_sync("callHierarchy/outgoingCalls", params, opts,
partial(outgoing_calls_handler, bang))
end end
M.incoming_calls_call = partial(M.incoming_calls, 0) M.incoming_calls_call = partial(M.incoming_calls, 0)

@ -13,7 +13,7 @@ end
local M = {} local M = {}
M.on_attach = function(client, bufnr) M.on_attach = function(client, bufnr)
log("on_attach")
local uri = vim.uri_from_bufnr(bufnr) local uri = vim.uri_from_bufnr(bufnr)
if uri == "file://" or uri == "file:///" or #uri < 11 then if uri == "file://" or uri == "file:///" or #uri < 11 then
log("skip for float buffer", uri) log("skip for float buffer", uri)
@ -51,6 +51,8 @@ M.on_attach = function(client, bufnr)
config.lsp[client.name].on_attach(client, bufnr) config.lsp[client.name].on_attach(client, bufnr)
end end
require("navigator.lspclient.mapping").setup(_NgConfigValues)
end end
-- M.setup = function(cfg) -- M.setup = function(cfg)

@ -210,6 +210,7 @@ local setups = {
end end
}, },
pyright = { pyright = {
on_attach = on_attach,
cmd = {"pyright-langserver", "--stdio"}, cmd = {"pyright-langserver", "--stdio"},
filetypes = {"python"}, filetypes = {"python"},
flags = {allow_incremental_sync = true, debounce_text_changes = 500}, flags = {allow_incremental_sync = true, debounce_text_changes = 500},
@ -224,6 +225,7 @@ local setups = {
} }
}, },
ccls = { ccls = {
on_attach = on_attach,
init_options = { init_options = {
compilationDatabaseDirectory = "build", compilationDatabaseDirectory = "build",
root_dir = [[ util.root_pattern("compile_commands.json", "compile_flags.txt", "CMakeLists.txt", "Makefile", ".git") or util.path.dirname ]], root_dir = [[ util.root_pattern("compile_commands.json", "compile_flags.txt", "CMakeLists.txt", "Makefile", ".git") or util.path.dirname ]],
@ -326,7 +328,7 @@ local function wait_lsp_startup(ft, retry, lsp_opts)
return true return true
end end
_Loading = false _Loading = false
end, 200) end, 300)
end end
end end

@ -46,6 +46,11 @@ local key_maps = {
{key = "<Leader>k", func = "require('navigator.dochighlight').hi_symbol()"} {key = "<Leader>k", func = "require('navigator.dochighlight').hi_symbol()"}
} }
local ccls_mappings = {
{key = "<Leader>gi", func = "require('navigator.cclshierarchy').incoming_calls()"},
{key = "<Leader>go", func = "require('navigator.cclshierarchy').outgoing_calls()"}
}
local function set_mapping(user_opts) local function set_mapping(user_opts)
local opts = {noremap = true, silent = true} local opts = {noremap = true, silent = true}
user_opts = user_opts or {} user_opts = user_opts or {}
@ -57,10 +62,6 @@ local function set_mapping(user_opts)
vim.api.nvim_buf_set_keymap(bufnr, ...) vim.api.nvim_buf_set_keymap(bufnr, ...)
end end
local function set_keymap(...)
vim.api.nvim_set_keymap(...)
end
-- local function buf_set_option(...) -- local function buf_set_option(...)
-- vim.api.nvim_buf_set_option(bufnr, ...) -- vim.api.nvim_buf_set_option(bufnr, ...)
-- end -- end
@ -94,6 +95,8 @@ local function set_mapping(user_opts)
local range_fmt = false local range_fmt = false
local doc_fmt = false local doc_fmt = false
local ccls = false
log(vim.lsp.buf_get_clients(0))
for _, value in pairs(vim.lsp.buf_get_clients(0)) do for _, value in pairs(vim.lsp.buf_get_clients(0)) do
if value == nil or value.resolved_capabilities == nil then if value == nil or value.resolved_capabilities == nil then
return return
@ -104,8 +107,24 @@ local function set_mapping(user_opts)
if value.resolved_capabilities.document_range_formatting then if value.resolved_capabilities.document_range_formatting then
range_fmt = true range_fmt = true
end end
log("override ccls", value.config)
if value.config.name == "ccls" then
ccls = true
end
end end
if ccls then
log("override ccls", ccls_mappings)
for _, value in pairs(ccls_mappings) do
f = "<Cmd>lua " .. value.func .. "<CR>"
local k = value.key
local m = value.mode or "n"
log(f, k, m)
set_keymap(m, k, f, opts)
end
end
-- if user_opts.cap.document_formatting then -- if user_opts.cap.document_formatting then
if doc_fmt then if doc_fmt then
buf_set_keymap("n", "<space>ff", "<cmd>lua vim.lsp.buf.formatting()<CR>", opts) buf_set_keymap("n", "<space>ff", "<cmd>lua vim.lsp.buf.formatting()<CR>", opts)

@ -13,7 +13,9 @@ function M.get_data_from_file(filename, startLine)
end end
local uri = "file:///" .. filename local uri = "file:///" .. filename
local bufnr = vim.uri_to_bufnr(uri) local bufnr = vim.uri_to_bufnr(uri)
vim.fn.bufload(bufnr) if not vim.api.nvim_buf_is_loaded(bufnr) then
vim.fn.bufload(bufnr)
end
local data = vim.api.nvim_buf_get_lines(bufnr, startLine, startLine + 8, false) local data = vim.api.nvim_buf_get_lines(bufnr, startLine, startLine + 8, false)
if data == nil or vim.tbl_isempty(data) then if data == nil or vim.tbl_isempty(data) then
startLine = nil startLine = nil

Loading…
Cancel
Save