treesitter support and rust client support

neovim_0_5
ray-x 3 years ago
parent 5e93e2ced2
commit d1d3966802

@ -1,7 +1,7 @@
# Navigator
GUI for Neovim (nightly) built-in LSP with a collection of most used LSP/treesitter functions.
Easy code navigation.
GUI for Neovim (nightly) built-in LSP with a collection of most used LSP/🌲Treesitter functions.
Easy code navigation through LSP symbols and 🌲Treesitter symbols.
# Features:
@ -18,6 +18,7 @@ After installed a handful of lsp plugins, I still got ~500 loc for lsp and still
to tune the plugins to fit my requirements. The plugin help user setup lspconfig with only a few lines of codes.
Seconde reason is that lots of plugins serve as an enhance version of quickfix, lots of improvement was made by
[lspsaga](https://github.com/glepnir/lspsaga.nvim), from which, the plugin was inspired.
It also the first plugin, IMO, that allows you to search in all treesitter symbols in the workspace.
# Similar projects / special mentions:
@ -90,6 +91,11 @@ Use <c-e> or `:q!` to kill the floating window, <up/down> to move and <c-o> to o
![code preview](https://github.com/ray-x/files/blob/master/img/navigator/preview_with_hl.jpg?raw=true)
### Treesitter symbol
Treetsitter symbols in all buffers
![treesitter](https://github.com/ray-x/files/blob/master/img/navigator/treesitter.jpg?raw=true)
### Call hierarchy (incomming/outgoing)
![incomming](https://github.com/ray-x/files/blob/master/img/navigator/incomming.jpg?raw=true)

@ -2,24 +2,26 @@
local lspconfig = nil
local lsp_status = nil
if not packer_plugins["neovim/nvim-lspconfig"] or not packer_plugins["neovim/nvim-lspconfig"].loaded then
vim.cmd [[packadd nvim-lspconfig]]
end
if not packer_plugins["nvim-lua/lsp-status.nvim"] or not packer_plugins["lsp-status.nvim"].loaded then
vim.cmd [[packadd lsp-status.nvim]]
lsp_status = require("lsp-status")
-- if lazyloading
vim.cmd [[packadd nvim-lspconfig]]
lspconfig = require "lspconfig"
end
lspconfig = require "lspconfig"
lsp_status = require("lsp-status")
local cap = vim.lsp.protocol.make_client_capabilities()
local on_attach = require("navigator.lspclient.attach").on_attach
local lsp_status_cfg = {
status_symbol = "",
indicator_errors = "", --'',
indicator_warnings = "", --'',
status_symbol = " ",
indicator_errors = " ", --' ',
indicator_warnings = " ", --' ',
indicator_info = "",
--'',
--' ',
indicator_hint = "💡",
indicator_ok = "",
indicator_ok = " ",
--'✔️',
spinner_frames = {"", "", "", "", "", "", "", ""},
select_symbol = function(cursor_pos, symbol)
@ -102,6 +104,22 @@ local clang_cfg = {
on_attach(client)
end
}
local rust_cfg = {
settings = {
["rust-analyzer"] = {
assist = {
importMergeBehavior = "last",
importPrefix = "by_self",
},
cargo = {
loadOutDirsFromCheck = true
},
procMacro = {
enable = true
},
}
}
}
local sqls_cfg = {
on_attach = function(client, bufnr)
@ -111,7 +129,7 @@ local sqls_cfg = {
require "sqls".setup {picker = "telescope"} -- or default
end,
settings = {
cmd = {"sqls", "-config", "$HOME/.config/sqls/config.yml"},
cmd = {"sqls", "-config", "$HOME/.config/sqls/config.yml"}
-- alterantively:
-- connections = {
-- {
@ -119,13 +137,6 @@ local sqls_cfg = {
-- datasourcename = 'host=127.0.0.1 port=5432 user=postgres password=password dbname=user_db sslmode=disable',
-- },
-- },
workspace = {
library = {
-- this loads the `lua` files from nvim into the runtime.
[vim.fn.expand("$vimruntime/lua")] = true,
[vim.fn.expand("~/repos/nvim/lua")] = true
}
}
}
}
-- lua setup
@ -168,34 +179,41 @@ local lua_cfg = {
}
}
}
local servers = {
"gopls",
"tsserver",
"flow",
"bashls",
"dockerls",
"pyls",
"jdtls",
"sumneko_lua",
"vimls",
"html",
"jsonls",
"cssls",
"yamlls",
"clangd",
"sqls",
"denols",
"dartls",
"dotls",
"kotlin_language_server",
"nimls",
"phpactor",
"r_language_server",
"rust_analyzer",
"terraformls"
}
local function lsp_status_setup()
local servers = {
"gopls",
"tsserver",
"flow",
"bashls",
"dockerls",
"pyls",
"sumneko_lua",
"vimls",
"html",
"jsonls",
"cssls",
"yamlls",
"clangd",
"sqls"
}
if lsp_status ~= nil then
lsp_status.register_progress()
for _, lspclient in ipairs(servers) do
if lsp_status ~= nl then
lsp_status.register_progress()
lsp_status.config(lsp_status_cfg)
end
require "utils.highlight".diagnositc_config_sign()
require "utils.highlight".add_highlight()
lsp_status.config(lsp_status_cfg)
end
require "utils.highlight".diagnositc_config_sign()
require "utils.highlight".add_highlight()
end
local function setup(user_opts)
@ -206,7 +224,7 @@ local function setup(user_opts)
lsp_status_setup()
for _, lspclient in ipairs({"tsserver", "bashls", "flow", "dockerls", "vimls", "html", "jsonls", "cssls", "yamlls"}) do
for _, lspclient in ipairs(servers) do
lspconfig[lspclient].setup {
message_level = vim.lsp.protocol.MessageType.error,
log_level = vim.lsp.protocol.MessageType.error,
@ -218,20 +236,10 @@ local function setup(user_opts)
lspconfig.gopls.setup(golang_setup)
lspconfig.sqls.setup(sqls_cfg)
require "lspconfig".sumneko_lua.setup(lua_cfg)
lspconfig.sumneko_lua.setup(lua_cfg)
lspconfig.clangd.setup(clang_cfg)
servers = {
"dockerls",
"bashls",
"rust_analyzer",
"pyls"
}
for _, server in ipairs(servers) do
lspconfig[server].setup {
on_attach = on_attach
}
end
lspconfig.rust_analyzer.setup(rust_cfg)
end
return {setup = setup, cap = cap}

@ -19,6 +19,8 @@ local key_maps = {
{key = "<c-]>", func = "definition()"},
{key = "gD", func = "declaration()"},
{key = "gp", func = "require('navigator.definition').definition_preview()"},
{key = "gT", func = "require('navigator.treesitter').buf_ts()"},
{key = "GT", func = "require('navigator.treesitter').bufs_ts()"},
{key = "K", func = "hover()"},
{key = "ga", mode = 'n', func = "code_action()"},

@ -7,31 +7,31 @@ local clone = require "guihua.util".clone
local symbol_kind = require "navigator.lspclient.lspkind".symbol_kind
local symbols_to_items = lsphelper.symbols_to_items
function M.document_symbols(opts)
assert(#vim.lsp.buf_get_clients() > 0, "Must have a client running")
opts = opts or {}
local params = vim.lsp.util.make_position_params()
params.context = {includeDeclaration = true}
params.query = ""
local results_lsp = vim.lsp.buf_request_sync(0, "textDocument/documentSymbol", params, opts.timeout or 3000)
local locations = {}
log(results_lsp)
for _, server_results in pairs(results_lsp) do
if server_results.result then
vim.list_extend(locations, vim.lsp.util.symbols_to_items(server_results.result) or {})
end
end
local lines = {}
for _, loc in ipairs(locations) do
table.insert(lines, string.format("%s:%s:%s", loc.filename, loc.lnum, loc.text))
end
if #lines > 0 then
gui.new_list_view({data = lines})
else
print("symbols not found")
end
end
-- function M.document_symbols(opts)
-- assert(#vim.lsp.buf_get_clients() > 0, "Must have a client running")
-- opts = opts or {}
-- local params = vim.lsp.util.make_position_params()
-- params.context = {includeDeclaration = true}
-- params.query = ""
-- local results_lsp = vim.lsp.buf_request_sync(0, "textDocument/documentSymbol", params, opts.timeout or 3000)
-- local locations = {}
-- log(results_lsp)
-- for _, server_results in pairs(results_lsp) do
-- if server_results.result then
-- vim.list_extend(locations, vim.lsp.util.symbols_to_items(server_results.result) or {})
-- end
-- end
-- local lines = {}
--
-- for _, loc in ipairs(locations) do
-- table.insert(lines, string.format("%s:%s:%s", loc.filename, loc.lnum, loc.text))
-- end
-- if #lines > 0 then
-- gui.new_list_view({data = lines})
-- else
-- print("symbols not found")
-- end
-- end
function M.workspace_symbols(opts)
opts = opts or {}

@ -0,0 +1,126 @@
local gui = require "navigator.gui"
local ts_locals = require "nvim-treesitter.locals"
local parsers = require "nvim-treesitter.parsers"
local ts_utils = require "nvim-treesitter.ts_utils"
local api = vim.api
local M = {}
local cwd = vim.fn.getcwd(0)
local log = require "navigator.util".log
local match_kinds = {
var = "👹", -- Vampaire
method = "🍔", -- mac
["function"] = "🤣", -- Fun
parameter = "", -- Pi
associated = "🤝",
namespace = "🚀",
type = "",
field = "🏈"
}
local get_icon = function(kind)
if match_kinds[kind] == nil then
return "🌲"
else
return match_kinds[kind]
end
end
local function get_smallest_context(source)
local scopes = ts_locals.get_scopes()
local current = source
while current ~= nil and not vim.tbl_contains(scopes, current) do
current = current:parent()
end
return current or nil
end
local function prepare_node(node, kind)
local matches = {}
if node.node then
table.insert(matches, {kind = get_icon(kind), def = node.node})
else
for name, item in pairs(node) do
vim.list_extend(matches, prepare_node(item, name))
end
end
return matches
end
local function get_all_nodes(bufnr)
bufnr = bufnr or 0
if not parsers.has_parser() then
print("ts not loaded")
end
local fname = vim.fn.expand("%:p:f")
local uri = vim.uri_from_fname(fname)
if bufnr ~= 0 then
uri = vim.uri_from_bufnr(bufnr)
fname = vim.uri_to_fname(uri)
end
local display_filename = fname:gsub(cwd .. "/", "./", 1)
local all_nodes = {}
-- Support completion-nvim customized label map
local customized_labels = vim.g.completion_customize_lsp_label or {}
-- Step 2 find correct completions
for _, def in ipairs(ts_locals.get_definitions(bufnr)) do
local nodes = prepare_node(def)
local item = {}
for _, node in ipairs(nodes) do
item.tsdata = node.def or {}
item.kind = node.kind
item.node_scope = get_smallest_context(item.tsdata)
local start_line_node, _, _ = item.tsdata:start()
item.node_text = ts_utils.get_node_text(item.tsdata, bufnr)[1]
item.full_text = vim.trim(api.nvim_buf_get_lines(bufnr, start_line_node, start_line_node + 1, false)[1] or "")
item.range = ts_utils.node_to_lsp_range(item.tsdata)
item.uri = uri
item.name = node.node_text
item.filename = fname
item.display_filename = display_filename
item.lnum = item.range.start.line + 1
item.text = string.format("[%s %10s]\t🧩 %s", item.kind, item.node_text, item.full_text)
table.insert(all_nodes, item)
end
end
return all_nodes
end
function M.buf_ts()
local all_nodes = get_all_nodes()
gui.new_list_view({items = all_nodes, prompt = true, rawdata = true, api = "🎄"})
end
local exclude_ft = {'scroll', 'help', 'NvimTree'}
local function exclude(fname)
for i = 1, #exclude_ft do
if string.find(fname, exclude_ft[i]) then return true end
end
return false
end
function M.bufs_ts()
local bufs = vim.api.nvim_list_bufs()
local ts_opened = {}
for _, buf in ipairs(bufs) do
local bname = vim.fn.bufname(buf)
if #bname > 0 and not exclude(bname) then
if vim.api.nvim_buf_is_loaded(buf) then
local all_nodes = get_all_nodes(buf)
if all_nodes ~= nil then
vim.list_extend(ts_opened, all_nodes)
end
end
end
end
if #ts_opened > 1 then
log(ts_opened)
gui.new_list_view({items = ts_opened, prompt = true, api = "🎄"})
end
end
return M

@ -45,19 +45,21 @@ function M.get_base(path)
end
local function getDir(path)
local data = {}
local len = #path
if len <= 1 then return nil end
local last_index = 1
for i = 2, len do
local cur_char = path:sub(i,i)
if cur_char == '/' then
local my_data = path:sub(last_index + 1, i - 1)
table.insert(data, my_data)
last_index = i
end
local data = {}
local len = #path
if len <= 1 then
return nil
end
local last_index = 1
for i = 2, len do
local cur_char = path:sub(i, i)
if cur_char == "/" then
local my_data = path:sub(last_index + 1, i - 1)
table.insert(data, my_data)
last_index = i
end
return data
end
return data
end
function M.get_relative_path(base_path, my_path)
@ -96,7 +98,7 @@ local default_config = {
level = "info"
}
M._log = require('guihua.log').new({level='info'}, true)
M._log = require("guihua.log").new({level = "info"}, true)
-- add log to you lsp.log
M.log = M._log.info

Loading…
Cancel
Save