update treesitter symbol layout

neovim_0_5
ray-x 3 years ago
parent 183002ff28
commit 23ea6b94de

@ -31,7 +31,7 @@ It also the first plugin, IMO, that allows you to search in all treesitter symbo
# Install
You can remove your lspconfig setup and use this plugin.
The plugin depends on [guihua.lua](https://github.com/ray-x/guihua.lua), which provides GUI and fzy support.
The plugin depends on [guihua.lua](https://github.com/ray-x/guihua.lua), which provides GUI and fzy support(thanks [romgrk](romgrk/fzy-lua-native)).
```vim
Plug 'ray-x/guihua.lua', {'do': 'cd lua/fzy && make' }

@ -96,7 +96,7 @@ function M.new_list_view(opts)
data = require "guihua.util".aggregate_filename(items, opts)
end
local wwidth = api.nvim_get_option("columns")
local width = config.width or opts.width or math.floor(wwidth * 0.8)
local width = math.min( opts.width or config.width or 120, math.floor(wwidth * 0.8))
local wheight = config.height or math.floor(api.nvim_get_option("lines") * 0.8)
local prompt = opts.prompt or false
if data and not vim.tbl_isempty(data) then

@ -3,7 +3,7 @@ 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 util = require'navigator.util'
local util = require "navigator.util"
local M = {}
local cwd = vim.fn.getcwd(0)
@ -13,7 +13,7 @@ local match_kinds = {
var = "👹", -- Vampaire
method = "🍔", -- mac
["function"] = "🤣", -- Fun
parameter = "", -- Pi
parameter = " ", -- Pi
associated = "🤝",
namespace = "🚀",
type = "",
@ -28,6 +28,35 @@ local get_icon = function(kind)
end
end
--- Get definitions of bufnr (unique and sorted by order of appearance).
--- This function copy from treesitter/refactor/navigation.lua
local function get_definitions(bufnr)
local local_nodes = ts_locals.get_locals(bufnr)
-- Make sure the nodes are unique.
local nodes_set = {}
for _, loc in ipairs(local_nodes) do
if loc.definition then
ts_locals.recurse_local_nodes(loc.definition, function(_, node, _, match)
-- lua doesn't compare tables by value,
-- use the value from byte count instead.
local _, _, start = node:start()
nodes_set[start] = {node = node, type = match or ""}
end)
end
end
-- Sort by order of appearance.
local definition_nodes = vim.tbl_values(nodes_set)
table.sort(definition_nodes, function (a, b)
local _, _, start_a = a.node:start()
local _, _, start_b = b.node:start()
return start_a < start_b
end)
return definition_nodes
end
local function get_smallest_context(source)
local scopes = ts_locals.get_scopes()
local current = source
@ -68,8 +97,32 @@ local function get_all_nodes(bufnr)
-- Support completion-nvim customized label map
local customized_labels = vim.g.completion_customize_lsp_label or {}
-- Force some types to act like they are parents
-- instead of neighbors of the next nodes.
local containers = {
["function"] = true,
["type"] = true,
["method"] = true
}
-- Step 2 find correct completions
for _, def in ipairs(ts_locals.get_definitions(bufnr)) do
local length = 10
local parents = {} -- stack of nodes a clever algorithm from treesiter refactor @Santos Gallegos
for _, def in ipairs(get_definitions(bufnr)) do
local n = #parents
for i = 1, n do
local index = n + 1 - i
local parent_def = parents[index]
if
ts_utils.is_parent(parent_def.node, def.node) or
(containers[parent_def.type] and ts_utils.is_parent(parent_def.node:parent(), def.node))
then
break
else
parents[index] = nil
end
end
parents[#parents + 1] = def
local nodes = prepare_node(def)
local item = {}
for _, node in ipairs(nodes) do
@ -78,18 +131,28 @@ local function get_all_nodes(bufnr)
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]
if item.node_text == '_' then goto continue end
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)
item.lnum, item.col, _ = def.node:start()
item.lnum = item.lnum + 1
item.col = item.col + 1
local indent=""
if #parents > 1 then indent = string.rep(' ', #parents - 1) .. '' end
item.text = string.format("%s%s%-10s\t🧩 %s", item.kind, indent, item.node_text, item.full_text)
if #item.text > length then
length = #item.text
end
table.insert(all_nodes, item)
::continue::
end
end
return all_nodes
return all_nodes, length
end
function M.buf_ts()
@ -97,8 +160,8 @@ function M.buf_ts()
error("treesitter not loaded")
return
end
local all_nodes = get_all_nodes()
gui.new_list_view({items = all_nodes, prompt = true, rawdata = true, api = "🎄"})
local all_nodes, width = get_all_nodes()
gui.new_list_view({items = all_nodes, prompt = true, rawdata = true, width = width + 10, api = "🎄"})
end
function M.bufs_ts()
@ -108,12 +171,16 @@ function M.bufs_ts()
end
local bufs = vim.api.nvim_list_bufs()
local ts_opened = {}
local max_length = 10
for _, buf in ipairs(bufs) do
local bname = vim.fn.bufname(buf)
if #bname > 0 and not util.exclude(bname) then
if vim.api.nvim_buf_is_loaded(buf) then
local all_nodes = get_all_nodes(buf)
local all_nodes, length = get_all_nodes(buf)
if all_nodes ~= nil then
if length > max_length then
max_length = length
end
vim.list_extend(ts_opened, all_nodes)
end
end
@ -121,7 +188,7 @@ function M.bufs_ts()
end
if #ts_opened > 1 then
log(ts_opened)
gui.new_list_view({items = ts_opened, prompt = true, api = "🎄"})
gui.new_list_view({items = ts_opened, prompt = true, width = max_length + 10, api = "🎄"})
end
end

@ -98,7 +98,7 @@ local default_config = {
level = "info"
}
M._log = require("guihua.log").new({level = "info"}, true)
M._log = require("guihua.log").new({level = "error"}, true)
-- add log to you lsp.log
M.log = M._log.info

Loading…
Cancel
Save