Side panel (#197)

* add sidepanel

* revert some changes and fix nil indent level

* Add side panel; bugfix for ctags
neovim_0.6^2
rayx 2 years ago committed by GitHub
parent 7bfd9157fe
commit 1f6103ed95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -5,7 +5,9 @@
- A plugin combines the power of LSP and 🌲🏡 Treesitter together. Not only provids a better highlight but also help you analyse symbol context effectively.
- Fuzzy search & build ctags symbols
- ctags fuzzy search & build ctags symbols
-
- [![a short intro of navigator](https://user-images.githubusercontent.com/1681295/147378905-51eede5f-e36d-48f4-9799-ae562949babe.jpeg)](https://youtu.be/P1kd7Y8AatE)
@ -94,7 +96,9 @@ variable is:
- ccls call hierarchy (Non-standard `ccls/call` API) supports
- Syntax folding based on treesitter folding algorithm. (It behaves similar to vs-code)
- Syntax folding based on treesitter or LSP_fold folding algorithm. (It behaves similar to vs-code); comment folding
- Treesitter symbols sidebar, LSP document symbole sidebar. Both with preview and folding
- Fully support LSP CodeAction, CodeLens, CodeLens action. Help you improve code quality.
@ -673,6 +677,13 @@ Using treesitter and LSP to view the symbol definition
![image](https://user-images.githubusercontent.com/1681295/139771978-bbc970a5-be9f-42cf-8942-3477485bd89c.png)
### Sidebar, folding, outline
Treesitter outline and Diagnostics
<img width="708" alt="image" src="https://user-images.githubusercontent.com/1681295/174791609-0023e68f-f1f4-4335-9ea2-d2360e9f0bfd.png">
<img width="733" alt="image" src="https://user-images.githubusercontent.com/1681295/174804579-26f87fbf-426b-46d0-a7a3-a5aab69c032f.png">
### GUI and multigrid support
You can load a different font size for floating win

@ -1,4 +1,4 @@
function! folding#foldexpr()
function! folding#ngfoldexpr()
" return luaeval(printf('require"navigator.foldinglsp".get_fold_indic(%d)', v:lnum))
return luaeval(printf('require"navigator.foldts".get_fold_indic(%d)', v:lnum))
endfunction

@ -54,6 +54,8 @@ end
local function ctags_gen()
local cmd = 'ctags' -- -x -n -u -f - ' .. vfn.expand('%:p')
local output = _NgConfigValues.ctags.tagfile
-- rm file first
util.rm_file(output)
local options = '-R --exclude=.git --exclude=node_modules --exclude=test --exclude=vendor --excmd=number '
if _NgConfigValues.ctags then
cmd = _NgConfigValues.ctags.cmd
@ -64,6 +66,7 @@ local function ctags_gen()
options = options .. '--language=' .. lang
cmd = cmd .. ' ' .. options
cmd = string.format('%s -f %s %s --language=%s', cmd, output, options, lang)
cmd = vim.split(cmd, ' ')
log(cmd)
vfn.jobstart(cmd, {
on_stdout = function(_, _, _)
@ -72,7 +75,7 @@ local function ctags_gen()
on_exit = function(_, data, _) -- id, data, event
-- log(vim.inspect(data) .. "exit")
if data and data.code ~= 0 then
if data and data ~= 0 then
return vim.notify(cmd .. ' failed ' .. tostring(data), vim.lsp.log_levels.ERROR)
else
vim.notify('ctags generated')
@ -108,10 +111,10 @@ local function ctags_symbols()
local ft = vim.o.ft
local result = symbols_to_items(items)
log(result)
if next(result) == nil then
return vim.notify('no symbols found')
end
log(result[1])
local opt = {
api = '',
ft = ft,

@ -350,8 +350,6 @@ end
M.show_buf_diagnostics = function()
if diagnostic_list[vim.bo.filetype] ~= nil then
-- log(diagnostic_list[vim.bo.filetype])
-- vim.fn.setqflist({}, " ", {title = "LSP", items = diagnostic_list[vim.bo.filetype]})
local results = diagnostic_list[vim.bo.filetype]
local display_items = {}
for _, client_items in pairs(results) do
@ -369,7 +367,7 @@ M.show_buf_diagnostics = function()
enable_preview_edit = true,
})
if listview == nil then
return log("nil listview")
return log('nil listview')
end
trace('new buffer', listview.bufnr)
if listview.bufnr then
@ -471,6 +469,43 @@ function M.show_diagnostics(pos)
end
end
function M.treesitter_and_diag_panel()
local Panel = require('guihua.panel')
local ft = vim.bo.filetype
local results = diagnostic_list[ft]
log(diagnostic_list, ft)
local bufnr = vim.api.nvim_get_current_buf()
local p = Panel:new({
header = 'treesitter',
render = function(b)
log('render for ', bufnr, b)
return require('navigator.treesitter').all_ts_nodes(b)
end,
})
p:add_section({
header = 'diagnostic',
render = function(bufnr)
if diagnostic_list[ft] ~= nil then
local display_items = {}
for _, client_items in pairs(results) do
for _, items in pairs(client_items) do
for _, it in pairs(items) do
log(it)
table.insert(display_items, it)
end
end
end
return display_items
else
return {}
end
end,
})
p:open(true)
end
function M.config(cfg)
cfg = cfg or {}
local default_cfg = {

@ -56,7 +56,6 @@ function M.setup_plugin()
M.active_folding_clients[client_id] = server_supports_folding
end
end
-- print(vim.inspect(M.active_folding_clients))
end
function M.update_folds()

@ -44,7 +44,7 @@ function M.setup_fold()
local current_window = api.nvim_get_current_win()
api.nvim_win_set_option(current_window, 'foldmethod', 'expr')
api.nvim_win_set_option(current_window, 'foldexpr', 'folding#foldexpr()')
api.nvim_win_set_option(current_window, 'foldexpr', 'folding#ngfoldexpr()')
end
-- This is cached on buf tick to avoid computing that multiple times

@ -1,7 +1,7 @@
local gui = require('navigator.gui')
local util = require('navigator.util')
local log = util.log
local trace = util.trace
local trace = util.log
local partial = util.partial
local lsphelper = require('navigator.lspwrapper')
@ -9,94 +9,162 @@ local path_sep = require('navigator.util').path_sep()
local path_cur = require('navigator.util').path_cur()
local cwd = vim.loop.cwd()
local M = {}
local function call_hierarchy_handler(direction, err, result, ctx, _, error_message)
local outgoing_calls_handler
local incoming_calls_handler
local function call_hierarchy_handler(direction, err, result, ctx, config)
log(direction, err, result, ctx, config)
if not result then
vim.notify('No call hierarchy items found', vim.lsp.log_levels.WARN)
return
end
trace('call_hierarchy', result)
-- trace('call_hierarchy', result)
local bufnr = vim.api.nvim_get_current_buf()
assert(next(vim.lsp.buf_get_clients(bufnr)), 'Must have a client running to use lsp_tags')
if err ~= nil then
log('dir', direction, 'result', result, 'err', err, ctx)
vim.notify('ERROR: ' .. error_message, vim.lsp.log_levels.WARN)
vim.notify('ERROR: ' .. err, vim.lsp.log_levels.WARN)
return
end
local items = {}
local items = ctx.items or {}
for _, call_hierarchy_call in pairs(result) do
local call_hierarchy_item = call_hierarchy_call[direction]
for _, call_hierarchy_result in pairs(result) do
local call_hierarchy_item = call_hierarchy_result[direction]
local kind = ''
if call_hierarchy_item.kind then
kind = require('navigator.lspclient.lspkind').symbol_kind(call_hierarchy_item.kind) .. ' '
end
-- for _, range in pairs(call_hierarchy_call.fromRanges) do
local range = call_hierarchy_item.range or call_hierarchy_item.selectionRange
local filename = assert(vim.uri_to_fname(call_hierarchy_item.uri))
local display_filename = filename:gsub(cwd .. path_sep, path_cur, 1)
call_hierarchy_item.detail = call_hierarchy_item.detail or ''
call_hierarchy_item.detail = string.gsub(call_hierarchy_item.detail, '\n', '')
trace(range, call_hierarchy_item)
trace(result, call_hierarchy_item)
local disp_item = {
uri = call_hierarchy_item.uri,
local disp_item = vim.tbl_deep_extend('force', {}, call_hierarchy_item)
disp_item = vim.tbl_deep_extend('force', disp_item, {
filename = filename,
display_filename = display_filename,
indent = ctx.depth,
text = kind .. call_hierarchy_item.name .. '' .. call_hierarchy_item.detail,
range = range,
lnum = range.start.line + 1,
col = range.start.character,
}
lnum = call_hierarchy_item.selectionRange.start.line + 1,
col = call_hierarchy_item.selectionRange.start.character,
})
table.insert(items, disp_item)
-- end
if ctx.depth or 0 > 0 then
local params = {
position = {
character = disp_item.selectionRange.start.character,
line = disp_item.selectionRange.start.line,
},
textDocument = {
uri = disp_item.uri,
},
}
local api = 'callHierarchy/outgoingCalls'
local handler = outgoing_calls_handler
if direction == 'incoming' then
api = 'callHierarchy/incomingCalls'
handler = incoming_calls_handler
end
lsphelper.call_sync(
api,
params,
ctx,
vim.lsp.with(
partial(handler, 0),
{ depth = ctx.depth - 1, direction = 'to', items = ctx.items, no_show = true }
)
)
end
end
log(items)
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, result, ctx, cfg)
local function incoming_calls_handler(_, err, result, ctx, cfg)
incoming_calls_handler = function(_, err, result, ctx, cfg)
local bufnr = vim.api.nvim_get_current_buf()
assert(next(vim.lsp.buf_get_clients(bufnr)), 'Must have a client running to use lsp hierarchy')
local results = call_hierarchy_handler_from(err, result, ctx, cfg, 'Incoming calls not found')
local ft = vim.api.nvim_buf_get_option(ctx.bufnr, 'ft')
gui.new_list_view({ items = results, ft = ft, api = '' })
local ft = vim.api.nvim_buf_get_option(ctx.bufnr or vim.api.nvim_get_current_buf(), 'ft')
if ctx.no_show then
return results
end
local win = gui.new_list_view({ items = results, ft = ft, api = '' })
return results, win
end
local function outgoing_calls_handler(_, err, result, ctx, cfg)
outgoing_calls_handler = function(_, err, result, ctx, cfg)
local results = call_hierarchy_handler_to(err, result, ctx, cfg, 'Outgoing calls not found')
local ft = vim.api.nvim_buf_get_option(ctx.bufnr, 'ft')
gui.new_list_view({ items = results, ft = ft, api = '' })
-- fzf_locations(bang, "", "Outgoing Calls", results, false)
if ctx.no_show then
return results
end
local win = gui.new_list_view({ items = results, ft = ft, api = '' })
return result, win
end
function M.incoming_calls(bang, opts)
local bufnr = vim.api.nvim_get_current_buf()
assert(next(vim.lsp.buf_get_clients(bufnr)), 'Must have a client running to use lsp hierarchy')
if not lsphelper.check_capabilities('callHierarchyProvider') then
local function request(method, params, handler)
return vim.lsp.buf_request(0, method, params, handler)
end
local function pick_call_hierarchy_item(call_hierarchy_items)
if not call_hierarchy_items then
return
end
if #call_hierarchy_items == 1 then
return call_hierarchy_items[1]
end
local items = {}
for i, item in pairs(call_hierarchy_items) do
local entry = item.detail or item.name
table.insert(items, string.format('%d. %s', i, entry))
end
local choice = vim.fn.inputlist(items)
if choice < 1 or choice > #items then
return
end
return choice
end
local function call_hierarchy(method, opts)
local params = vim.lsp.util.make_position_params()
lsphelper.call_sync('callHierarchy/incomingCalls', params, opts, partial(incoming_calls_handler, bang))
opts = opts or {}
request(
'textDocument/prepareCallHierarchy',
params,
vim.lsp.with(function(err, result, ctx)
if err then
vim.notify(err.message, vim.log.levels.WARN)
return
end
local call_hierarchy_item = pick_call_hierarchy_item(result)
log('result', result, 'items', call_hierarchy_item)
local client = vim.lsp.get_client_by_id(ctx.client_id)
if client then
client.request(method, { item = call_hierarchy_item }, nil, ctx.bufnr)
else
vim.notify(
string.format('Client with id=%d disappeared during call hierarchy request', ctx.client_id),
vim.log.levels.WARN
)
end
end, { direction = method, depth = opts.depth })
)
end
function M.outgoing_calls(bang, opts)
local bufnr = vim.api.nvim_get_current_buf()
assert(next(vim.lsp.buf_get_clients(bufnr)), 'Must have a client running to use lsp_tags')
if not lsphelper.check_capabilities('callHierarchyProvider') then
return
end
function M.incoming_calls(opts)
call_hierarchy('callHierarchy/incomingCalls', opts)
end
local params = vim.lsp.util.make_position_params()
lsphelper.call_sync('callHierarchy/outgoingCalls', params, opts, partial(outgoing_calls_handler, bang))
function M.outgoing_calls(opts)
call_hierarchy('callHierarchy/outgoingCalls', opts)
end
M.incoming_calls_call = partial(M.incoming_calls, 0)

@ -24,7 +24,25 @@ end
local util = lspconfig.util
local config = require('navigator').config_values()
local disabled_ft = {
'NvimTree',
'guihua',
'clap_input',
'clap_spinner',
'vista',
'vista_kind',
'TelescopePrompt',
'guihua_rust',
'csv',
'txt',
'defx',
'packer',
'gitcommit',
'windline',
'notify',
'nofile',
'',
}
-- local cap = vim.lsp.protocol.make_client_capabilities()
local on_attach = require('navigator.lspclient.attach').on_attach
-- gopls["ui.completion.usePlaceholders"] = true
@ -708,6 +726,14 @@ local function get_cfg(client)
end
end
local function ft_disabled(ft)
for i = 1, #disabled_ft do
if ft == disabled_ft[i] then
return true
end
end
end
local function setup(user_opts, cnt)
user_opts = user_opts or {}
local ft = vim.bo.filetype
@ -744,28 +770,10 @@ local function setup(user_opts, cnt)
log('navigator was loaded for ft', ft, bufnr)
return
end
local disable_ft = {
'NvimTree',
'guihua',
'clap_input',
'clap_spinner',
'vista',
'vista_kind',
'TelescopePrompt',
'guihua_rust',
'csv',
'txt',
'defx',
'packer',
'gitcommit',
'windline',
'notify',
}
for i = 1, #disable_ft do
if ft == disable_ft[i] then
trace('navigator disabled for ft or it is loaded', ft)
return
end
if ft_disabled(ft) then
trace('navigator disabled for ft or it is loaded', ft)
return
end
if _NgConfigValues.lsp.servers then
add_servers(_NgConfigValues.lsp.servers)
@ -840,4 +848,12 @@ local function on_filetype()
setup({ bufnr = bufnr })
end
return { setup = setup, get_cfg = get_cfg, lsp = servers, add_servers = add_servers, on_filetype = on_filetype }
return {
setup = setup,
get_cfg = get_cfg,
lsp = servers,
add_servers = add_servers,
on_filetype = on_filetype,
disabled_ft = disabled_ft,
ft_disabled = ft_disabled,
}

@ -63,11 +63,13 @@ local key_maps = {
}
local commands = {
[[command! -nargs=* Nctags lua require("navigator.ctags").ctags({<f-args>})]],
[[command! -nargs=* Nctags lua require("navigator.ctags").ctags(<f-args>)]],
"command! -nargs=0 LspLog lua require'navigator.lspclient.config'.open_lsp_log()",
"command! -nargs=0 LspRestart lua require'navigator.lspclient.config'.reload_lsp()",
"command! -nargs=0 LspToggleFmt lua require'navigator.lspclient.mapping'.toggle_lspformat()<CR>",
"command! -nargs=0 LspKeymaps lua require'navigator.lspclient.mapping'.get_keymaps_help()<CR>",
"command! -nargs=0 LspSymbols lua require'navigator.symbols'.side_panel()<CR>",
"command! -nargs=0 TSymbols lua require'navigator.treesitter'.side_panel()<CR>",
}
local key_maps_help = {}
@ -179,7 +181,7 @@ local function set_mapping(lsp_info)
elseif string.find(value.func, 'format') then
fmtkey = value.key
end
log('binding', k, f)
trace('binding', k, f)
set_keymap(m, k, f, opts)
end
@ -279,12 +281,12 @@ function M.setup(user_opts)
local client = user_opts.client or {}
local cap = client.server_capabilities or vim.lsp.protocol.make_client_capabilities()
log('lsp cap:', cap)
log('lsp cap:', cap.codeActionProvider)
if cap.call_hierarchy or cap.callHierarchyProvider then
vim.lsp.handlers['callHierarchy/incomingCalls'] = require('navigator.hierarchy').incoming_calls_handler
vim.lsp.handlers['callHierarchy/outgoingCalls'] = require('navigator.hierarchy').outgoing_calls_handler
end
-- if cap.call_hierarchy or cap.callHierarchyProvider then
-- vim.lsp.handlers['callHierarchy/incomingCalls'] = require('navigator.hierarchy').incoming_calls_handler
-- vim.lsp.handlers['callHierarchy/outgoingCalls'] = require('navigator.hierarchy').outgoing_calls_handler
-- end
vim.lsp.handlers['textDocument/references'] = require('navigator.reference').reference_handler
-- vim.lsp.handlers["textDocument/codeAction"] = require"navigator.codeAction".code_action_handler

@ -145,18 +145,20 @@ end
function M.call_sync(method, params, opts, handler)
params = params or {}
opts = opts or {}
local results_lsp, err = lsp.buf_request_sync(0, method, params, opts.timeout or vim.g.navtator_timeout or 1000)
log(method, params)
local results_lsp, err = lsp.buf_request_sync(opts.bufnr or 0, method, params, opts.timeout or 1000)
handler(err, extract_result(results_lsp), { method = method }, nil)
return handler(err, extract_result(results_lsp), { method = method, no_show = opts.no_show }, nil)
end
function M.call_async(method, params, handler)
function M.call_async(method, params, handler, bufnr)
params = params or {}
local callback = function(...)
util.show(...)
handler(...)
end
return lsp.buf_request(0, method, params, callback)
bufnr = bufnr or 0
return lsp.buf_request(bufnr, method, params, callback)
-- results_lsp, canceller
end

@ -11,7 +11,6 @@ function M.workspace_symbols(query)
local bufnr = vim.api.nvim_get_current_buf()
local params = { query = query }
vim.lsp.for_each_buffer_client(bufnr, function(client, _, _bufnr)
-- if client.resolved_capabilities.workspace_symbol then
if client.server_capabilities.workspaceSymbolProvider then
client.request('workspace/symbol', params, M.workspace_symbol_handler, _bufnr)
end
@ -33,7 +32,6 @@ function M.document_symbols(opts)
params.context = { includeDeclaration = true }
params.query = opts.prompt or ''
vim.lsp.for_each_buffer_client(bufnr, function(client, _, _bufnr)
-- if client.resolved_capabilities.document_symbol then
if client.server_capabilities.documentSymbolProvider then
client.request('textDocument/documentSymbol', params, M.document_symbol_handler, _bufnr)
end
@ -51,7 +49,7 @@ M.document_symbol_handler = function(err, result, ctx)
end
if not result or vim.tbl_isempty(result) then
vim.notify('symbol' .. query .. 'not found for buf' .. vim.inspect(ctx), vim.lsp.log_levels.WARN)
vim.notify('symbol ' .. query .. ' not found for buf ' .. vim.inspect(ctx), vim.lsp.log_levels.WARN)
return
end
local locations = {}
@ -66,7 +64,7 @@ M.document_symbol_handler = function(err, result, ctx)
item.name = result[i].name
item.range = result[i].range or result[i].location.range
if item.range == nil then
log("range missing in result", result[i])
log('range missing in result', result[i])
end
item.uri = uri
item.selectionRange = result[i].selectionRange
@ -79,6 +77,10 @@ M.document_symbol_handler = function(err, result, ctx)
item.text = '[' .. kind .. ']' .. item.name .. ' ' .. item.detail
item.filename = fname
item.indent_level = 1
item.type = kind
item.node_text = item.name
table.insert(locations, item)
if result[i].children ~= nil then
@ -88,16 +90,23 @@ M.document_symbol_handler = function(err, result, ctx)
child.name = c.name
child.range = c.range or c.location.range
local ckind = symbol_kind(child.kind)
child.node_text = child.name
child.type = ckind
child.selectionRange = c.selectionRange
child.filename = fname
child.uri = uri
child.lnum = child.range.start.line + 1
child.detail = c.detail or ''
child.indent_level = 2
child.text = '' .. ckind .. '' .. child.name .. ' ' .. child.detail
table.insert(locations, child)
end
end
end
if ctx.no_show then
return locations
end
local ft = vim.api.nvim_buf_get_option(bufnr, 'ft')
gui.new_list_view({
@ -133,4 +142,26 @@ M.workspace_symbol_handler = function(err, result, ctx, cfg)
gui.new_list_view({ items = items, prompt = true, ft = ft, rowdata = true, api = '' })
end
function M.side_panel()
local Panel = require('guihua.panel')
local buf = vim.api.nvim_get_current_buf()
local p = Panel:new({
render = function(bufnr)
local ft = vim.api.nvim_buf_get_option(bufnr, 'buftype')
if ft == 'nofile' or ft == 'guihua' or ft == 'prompt' then
return
end
local params = vim.lsp.util.make_range_params()
local sync_req = require('navigator.lspwrapper').call_sync
return sync_req(
'textDocument/documentSymbol',
params,
{ timeout = 1000, bufnr = bufnr, no_show = true },
vim.lsp.with(M.document_symbol_handler, { no_show = true })
)
end,
})
p:open(true)
end
return M

@ -110,7 +110,6 @@ end
--- 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
@ -291,8 +290,12 @@ local function get_all_nodes(bufnr, filter, summary)
vim.notify('get_all_node invalide bufnr', vim.lsp.log_levels.WARN)
end
summary = summary or false
local ft = vim.api.nvim_buf_get_option(bufnr, 'filetype')
if not parsers.has_parser() then
vim.notify('ts not loaded', vim.lsp.log_levels.Debug)
if not require('navigator.lspclient.clients').ft_disabled(ft) then
vim.notify('ts not loaded ' .. ft, vim.lsp.log_levels.Debug)
end
return {}
end
local path_sep = require('navigator.util').path_sep()
@ -311,7 +314,7 @@ local function get_all_nodes(bufnr, filter, summary)
['arrow_function'] = true,
['type'] = true,
['class'] = true,
['var'] = true,
-- ['var'] = true,
['struct'] = true,
['method'] = true,
}
@ -327,17 +330,31 @@ local function get_all_nodes(bufnr, filter, summary)
-- Step 2 find correct completions
local length = 10
local parents = {} -- stack of nodes a clever algorithm from treesiter refactor @Santos Gallegos
local loaded_symbol = {}
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]
log(parent_def.type, parent_def.node:type(), vim.treesitter.get_node_text(parent_def.node, bufnr))
log(def.node:type(), vim.treesitter.get_node_text(def.node, bufnr))
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))
or (
containers[parent_def.type]
and (
ts_utils.is_parent(parent_def.node:parent(), def.node)
or (
parent_def.node:parent():type():find('dot_index')
and ts_utils.is_parent(parent_def.node:parent():parent(), def.node)
)
)
)
then
log('is parent', i, index)
break
else
log('leave node', i, index)
parents[index] = nil
end
end
@ -353,6 +370,10 @@ local function get_all_nodes(bufnr, filter, summary)
trace(item.type, item.kind)
goto continue
end
if item.type == 'associated' then
goto continue
end
local tsdata = node.def
if node.def == nil then
@ -369,20 +390,40 @@ local function get_all_nodes(bufnr, filter, summary)
if is_func then
-- hack for lua and maybe other language aswell
local parent = tsdata:parent()
if parent ~= nil and parent:type() == 'function_name' or parent:type() == 'function_name_field' then
if parent ~= nil then
log(parent:type(), vim.treesitter.get_node_text(parent, bufnr), item.node_text, item.type)
end
if
parent ~= nil
and (
parent:type() == 'function_name'
-- or parent:type() == 'function'
-- or parent:type() == 'function_declaration' -- this bring in too much info
or parent:type() == 'method_name'
or parent:type() == 'function_name_field'
)
then
-- replace function name
item.node_text = vim.treesitter.get_node_text(parent, bufnr)
local cut = item.node_text:find('[\n\r]')
if cut then
item.node_text = item.node_text:sub(1, cut - 1)
end
log(parent:type(), item.node_text)
end
end
trace(item.node_text, item.kind, item.type)
if scope ~= nil then
-- it is strange..
if not is_func and summary then
log(item.node_text, item.type)
goto continue
end
item.node_scope = ts_utils.node_to_lsp_range(scope)
end
if item.node_text == '_' then
goto continue
end
if summary then
if item.node_scope ~= nil then
table.insert(all_nodes, item)
@ -394,7 +435,6 @@ local function get_all_nodes(bufnr, filter, summary)
tsdata:type(),
item.node_text,
item.kind,
item.node_text,
'range',
item.node_scope.start.line,
item.node_scope['end'].line
@ -405,10 +445,9 @@ local function get_all_nodes(bufnr, filter, summary)
item.range = ts_utils.node_to_lsp_range(tsdata)
local start_line_node, _, _ = tsdata:start()
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 '')
local line_text = api.nvim_buf_get_lines(bufnr, start_line_node, start_line_node + 1, false)[1] or ''
item.full_text = vim.trim(line_text)
item.full_text = item.full_text:gsub('%s*[%[%(%{]*%s*$', '')
item.uri = uri
@ -423,7 +462,23 @@ local function get_all_nodes(bufnr, filter, summary)
indent = string.rep(' ', #parents - 1) .. ''
end
item.indent = indent
item.indent_level = #parents
item.indent_level = #parents -- maybe use real indent level ?
if item.indent_level <= 1 then
local sp = string.match(line_text, '(%s*)')
log(line_text, #sp)
if sp then
local indent_level = #sp / (vim.o.shiftwidth or 4) + 1
item.indent_level = math.max(item.indent_level, indent_level)
end
end
if #parents > 0 then
log(parents[1].type, vim.treesitter.get_node_text(parents[1].node, bufnr))
if parents[2] then
log(parents[2].type, vim.treesitter.get_node_text(parents[2].node, bufnr))
end
else
log('root node')
end
if #all_nodes >= 1 then
all_nodes[#all_nodes].next_indent_level = #parents
end
@ -432,7 +487,13 @@ local function get_all_nodes(bufnr, filter, summary)
if #item.text > length then
length = #item.text
end
table.insert(all_nodes, item)
if
loaded_symbol[item.node_text .. item.kind] == nil
or not util.range_inside(loaded_symbol[item.node_text .. item.kind], item.node_scope)
then
table.insert(all_nodes, item)
loaded_symbol[item.node_text .. item.kind] = item.node_scope
end
::continue::
end
end
@ -446,8 +507,12 @@ local function get_all_nodes(bufnr, filter, summary)
end
function M.buf_func(bufnr)
local ft = vim.api.nvim_buf_get_option(bufnr, 'buftype')
if vim.api.nvim_buf_get_option(bufnr, 'buftype') == 'nofile' then
return
end
if not ok or ts_locals == nil then
error('treesitter not loaded')
error('treesitter not loaded: ' .. ft)
return
end
@ -492,15 +557,33 @@ function M.buf_func(bufnr)
return all_nodes, width
end
function M.buf_ts()
function M.all_ts_nodes(bufnr)
if ts_locals == nil then
error('treesitter not loaded')
return
end
local bufnr = api.nvim_get_current_buf()
local bufnr = bufnr or api.nvim_get_current_buf()
local all_nodes, width = get_all_nodes(bufnr)
return all_nodes, width
end
function M.side_panel()
Panel = require('guihua.panel')
local bufnr = api.nvim_get_current_buf()
local p = Panel:new({
header = 'treesitter',
render = function(b)
log('render for ', bufnr, b)
return require('navigator.treesitter').all_ts_nodes(b)
end,
})
p:open(true)
end
function M.buf_ts()
local all_nodes, width = M.all_ts_nodes()
local bufnr = api.nvim_get_current_buf()
local ft = vim.api.nvim_buf_get_option(bufnr, 'ft')
local listview = gui.new_list_view({
items = all_nodes,
@ -512,7 +595,7 @@ function M.buf_ts()
width = width + 10,
api = _NgConfigValues.icons.treesitter_defult,
})
return listview, all_nodes, width
return listview, all_nodes, width
end
M.get_all_nodes = get_all_nodes

@ -71,6 +71,9 @@ function M.io_read(filename, total)
return content
end
function M.rm_file(filename)
return os.remove(filename)
end
function M.file_exists(name)
local f = io.open(name, "r")
@ -417,9 +420,9 @@ function M.mk_handler(fn)
end
function M.partial(func, arg)
return (M.mk_handler(function(...)
return function(...)
return func(arg, ...)
end))
end
end
function M.empty(t)
@ -443,7 +446,7 @@ function M.encoding(client)
end
local oe = client.offset_encoding
if oe == nil then
return 'utf-16'
return 'utf-8'
end
if type(oe) == 'table' then
return oe[1]
@ -465,4 +468,14 @@ function M.info(msg)
vim.notify('INF: ' .. msg, vim.lsp.log_levels.INFO)
end
function M.range_inside(outer, inner)
if outer == nil or inner == nil then
return false
end
if outer.start == nil or outer['end'] == nil or inner.start == nil or inner['end'] == nil then
return false
end
return outer.start.line <= inner.start.line and outer['end'].line >= inner['end'].line
end
return M

Loading…
Cancel
Save