treesitter support and rust client support

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

@ -1,7 +1,7 @@
# Navigator # Navigator
GUI for Neovim (nightly) built-in LSP with a collection of most used LSP/treesitter functions. GUI for Neovim (nightly) built-in LSP with a collection of most used LSP/🌲Treesitter functions.
Easy code navigation. Easy code navigation through LSP symbols and 🌲Treesitter symbols.
# Features: # 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. 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 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. [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: # 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) ![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) ### Call hierarchy (incomming/outgoing)
![incomming](https://github.com/ray-x/files/blob/master/img/navigator/incomming.jpg?raw=true) ![incomming](https://github.com/ray-x/files/blob/master/img/navigator/incomming.jpg?raw=true)

@ -2,24 +2,26 @@
local lspconfig = nil local lspconfig = nil
local lsp_status = 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 if not packer_plugins["nvim-lua/lsp-status.nvim"] or not packer_plugins["lsp-status.nvim"].loaded then
vim.cmd [[packadd lsp-status.nvim]] vim.cmd [[packadd lsp-status.nvim]]
lsp_status = require("lsp-status")
-- if lazyloading -- if lazyloading
vim.cmd [[packadd nvim-lspconfig]]
lspconfig = require "lspconfig"
end end
lspconfig = require "lspconfig"
lsp_status = require("lsp-status")
local cap = vim.lsp.protocol.make_client_capabilities() local cap = vim.lsp.protocol.make_client_capabilities()
local on_attach = require("navigator.lspclient.attach").on_attach local on_attach = require("navigator.lspclient.attach").on_attach
local lsp_status_cfg = { local lsp_status_cfg = {
status_symbol = "", status_symbol = " ",
indicator_errors = "", --'', indicator_errors = " ", --' ',
indicator_warnings = "", --'', indicator_warnings = " ", --' ',
indicator_info = "", indicator_info = "",
--'', --' ',
indicator_hint = "💡", indicator_hint = "💡",
indicator_ok = "", indicator_ok = " ",
--'✔️', --'✔️',
spinner_frames = {"", "", "", "", "", "", "", ""}, spinner_frames = {"", "", "", "", "", "", "", ""},
select_symbol = function(cursor_pos, symbol) select_symbol = function(cursor_pos, symbol)
@ -102,6 +104,22 @@ local clang_cfg = {
on_attach(client) on_attach(client)
end end
} }
local rust_cfg = {
settings = {
["rust-analyzer"] = {
assist = {
importMergeBehavior = "last",
importPrefix = "by_self",
},
cargo = {
loadOutDirsFromCheck = true
},
procMacro = {
enable = true
},
}
}
}
local sqls_cfg = { local sqls_cfg = {
on_attach = function(client, bufnr) on_attach = function(client, bufnr)
@ -111,7 +129,7 @@ local sqls_cfg = {
require "sqls".setup {picker = "telescope"} -- or default require "sqls".setup {picker = "telescope"} -- or default
end, end,
settings = { settings = {
cmd = {"sqls", "-config", "$HOME/.config/sqls/config.yml"}, cmd = {"sqls", "-config", "$HOME/.config/sqls/config.yml"}
-- alterantively: -- alterantively:
-- connections = { -- 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', -- 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 -- 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 function lsp_status_setup()
local servers = { if lsp_status ~= nil then
"gopls", lsp_status.register_progress()
"tsserver",
"flow",
"bashls",
"dockerls",
"pyls",
"sumneko_lua",
"vimls",
"html",
"jsonls",
"cssls",
"yamlls",
"clangd",
"sqls"
}
for _, lspclient in ipairs(servers) do lsp_status.config(lsp_status_cfg)
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()
end end
require "utils.highlight".diagnositc_config_sign()
require "utils.highlight".add_highlight()
end end
local function setup(user_opts) local function setup(user_opts)
@ -206,7 +224,7 @@ local function setup(user_opts)
lsp_status_setup() 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 { lspconfig[lspclient].setup {
message_level = vim.lsp.protocol.MessageType.error, message_level = vim.lsp.protocol.MessageType.error,
log_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.gopls.setup(golang_setup)
lspconfig.sqls.setup(sqls_cfg) lspconfig.sqls.setup(sqls_cfg)
require "lspconfig".sumneko_lua.setup(lua_cfg) lspconfig.sumneko_lua.setup(lua_cfg)
lspconfig.clangd.setup(clang_cfg) lspconfig.clangd.setup(clang_cfg)
servers = {
"dockerls",
"bashls",
"rust_analyzer",
"pyls"
}
for _, server in ipairs(servers) do lspconfig.rust_analyzer.setup(rust_cfg)
lspconfig[server].setup {
on_attach = on_attach
}
end
end end
return {setup = setup, cap = cap} return {setup = setup, cap = cap}

@ -19,6 +19,8 @@ local key_maps = {
{key = "<c-]>", func = "definition()"}, {key = "<c-]>", func = "definition()"},
{key = "gD", func = "declaration()"}, {key = "gD", func = "declaration()"},
{key = "gp", func = "require('navigator.definition').definition_preview()"}, {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 = "K", func = "hover()"},
{key = "ga", mode = 'n', func = "code_action()"}, {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 symbol_kind = require "navigator.lspclient.lspkind".symbol_kind
local symbols_to_items = lsphelper.symbols_to_items local symbols_to_items = lsphelper.symbols_to_items
function M.document_symbols(opts) -- function M.document_symbols(opts)
assert(#vim.lsp.buf_get_clients() > 0, "Must have a client running") -- assert(#vim.lsp.buf_get_clients() > 0, "Must have a client running")
opts = opts or {} -- opts = opts or {}
local params = vim.lsp.util.make_position_params() -- local params = vim.lsp.util.make_position_params()
params.context = {includeDeclaration = true} -- params.context = {includeDeclaration = true}
params.query = "" -- params.query = ""
local results_lsp = vim.lsp.buf_request_sync(0, "textDocument/documentSymbol", params, opts.timeout or 3000) -- local results_lsp = vim.lsp.buf_request_sync(0, "textDocument/documentSymbol", params, opts.timeout or 3000)
local locations = {} -- local locations = {}
log(results_lsp) -- log(results_lsp)
for _, server_results in pairs(results_lsp) do -- for _, server_results in pairs(results_lsp) do
if server_results.result then -- if server_results.result then
vim.list_extend(locations, vim.lsp.util.symbols_to_items(server_results.result) or {}) -- vim.list_extend(locations, vim.lsp.util.symbols_to_items(server_results.result) or {})
end -- end
end -- end
local lines = {} -- local lines = {}
--
for _, loc in ipairs(locations) do -- for _, loc in ipairs(locations) do
table.insert(lines, string.format("%s:%s:%s", loc.filename, loc.lnum, loc.text)) -- table.insert(lines, string.format("%s:%s:%s", loc.filename, loc.lnum, loc.text))
end -- end
if #lines > 0 then -- if #lines > 0 then
gui.new_list_view({data = lines}) -- gui.new_list_view({data = lines})
else -- else
print("symbols not found") -- print("symbols not found")
end -- end
end -- end
function M.workspace_symbols(opts) function M.workspace_symbols(opts)
opts = opts or {} 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 end
local function getDir(path) local function getDir(path)
local data = {} local data = {}
local len = #path local len = #path
if len <= 1 then return nil end if len <= 1 then
local last_index = 1 return nil
for i = 2, len do end
local cur_char = path:sub(i,i) local last_index = 1
if cur_char == '/' then for i = 2, len do
local my_data = path:sub(last_index + 1, i - 1) local cur_char = path:sub(i, i)
table.insert(data, my_data) if cur_char == "/" then
last_index = i local my_data = path:sub(last_index + 1, i - 1)
end table.insert(data, my_data)
last_index = i
end end
return data end
return data
end end
function M.get_relative_path(base_path, my_path) function M.get_relative_path(base_path, my_path)
@ -96,7 +98,7 @@ local default_config = {
level = "info" 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 -- add log to you lsp.log
M.log = M._log.info M.log = M._log.info

Loading…
Cancel
Save