From e7623f125aff7a1c753abcb06390f702bdc3f429 Mon Sep 17 00:00:00 2001 From: ray-x Date: Mon, 6 Nov 2023 14:25:09 +1100 Subject: [PATCH] bugfix ts context not shown for off-page entries --- lua/navigator.lua | 1 + lua/navigator/lspwrapper.lua | 56 ++++++++++++++++------------------- lua/navigator/reference.lua | 57 +++++++++++++++++++++++------------- lua/navigator/treesitter.lua | 18 ++++++++---- lua/navigator/util.lua | 27 ++++++++++------- 5 files changed, 90 insertions(+), 69 deletions(-) diff --git a/lua/navigator.lua b/lua/navigator.lua index ef464a1..8a04e73 100644 --- a/lua/navigator.lua +++ b/lua/navigator.lua @@ -34,6 +34,7 @@ _NgConfigValues = { treesitter_analysis = true, -- treesitter variable context treesitter_navigation = true, -- bool|table treesitter_analysis_max_num = 100, -- how many items to run treesitter analysis + treesitter_analysis_max_fnum = 20, -- how many files to run treesitter analysis treesitter_analysis_condense = true, -- short format of function treesitter_analysis_depth = 3, -- max depth transparency = 50, -- 0 ~ 100 blur the main window, 100: fully transparent, 0: opaque, set to nil to disable it diff --git a/lua/navigator/lspwrapper.lua b/lua/navigator/lspwrapper.lua index b749eea..622540d 100644 --- a/lua/navigator/lspwrapper.lua +++ b/lua/navigator/lspwrapper.lua @@ -9,9 +9,10 @@ local log = require('navigator.util').log local lerr = require('navigator.util').error local trace = require('navigator.util').trace local symbol_kind = require('navigator.lspclient.lspkind').symbol_kind -local cwd = vim.loop.cwd() - -local is_win = vim.loop.os_uname().sysname:find('Windows') +local uv = vim.uv or vim.loop +local cwd = uv.cwd() +local os_name = uv.os_uname().sysname +local is_win = os_name:find('Windows') or os_name:find('MINGW') local path_sep = require('navigator.util').path_sep() local path_cur = require('navigator.util').path_cur() @@ -264,24 +265,6 @@ local function find_ts_func_by_range(funcs, range) return result end -local function order_locations(locations) - table.sort(locations, function(i, j) - if i == nil or j == nil or i.uri == nil or j.uri == nil then - -- log(i, j) - return false - end - if i.uri == j.uri then - if i.range and i.range.start then - return i.range.start.line < j.range.start.line - end - return false - else - return i.uri < j.uri - end - end) - return locations -end - local function slice_locations(locations, max_items) local cut = -1 if #locations > max_items then @@ -326,28 +309,32 @@ end function M.locations_to_items(locations, ctx) ctx = ctx or {} - local max_items = ctx.max_items or 100000 -- + local max_items = ctx.max_items or 1000 -- + log(ctx, max_items) local client_id = ctx.client_id or 1 local enc = util.encoding(client_id) if not locations or vim.tbl_isempty(locations) then vim.notify('list not avalible', vim.log.levels.WARN) return end - local width = 4 + local width = 4 -- text max width local items = {} -- items and locations may not matching local uri_def = {} - order_locations(locations) local second_part locations, second_part = slice_locations(locations, max_items) + if second_part and #second_part > 0 then + log(#locations, locations[1], #second_part, second_part and second_part[1]) + end trace(locations) vim.cmd([[set eventignore+=FileType]]) local unload_bufnrs = {} + local file_cnt = {} for i, loc in ipairs(locations) do local item = lsp.util.locations_to_items({ loc }, enc)[1] item.range = locations[i].range or locations[i].targetRange @@ -355,14 +342,17 @@ function M.locations_to_items(locations, ctx) item.definition = locations[i].definition if is_win then - log(item.uri) -- file:///C:/path/to/file - log(cwd) + log(item.uri, cwd) -- file:///C:/path/to/file end - -- only load top 30 file. - local proj_file = item.uri:find(cwd) or is_win or i < _NgConfigValues.treesitter_analysis_max_num + file_cnt[item.uri] = (file_cnt[item.uri] or 0) + 1 + -- only load top 30 file.items + local proj_file = (item.uri:find(cwd) or is_win) and i < _NgConfigValues.treesitter_analysis_max_num and table.getn(file_cnt) < _NgConfigValues.treesitter_analysis_max_fnum -- getn deprecated, but it is the best solution for getting dict size local unload, def local context = '' - if TS_analysis_enabled and proj_file and not ctx.no_show then + if not proj_file then + log('not proj file', i, item.uri) + end + if TS_analysis_enabled and not ctx.no_show and proj_file then local ts_context = nts.ref_context local bufnr = vim.uri_to_bufnr(item.uri) @@ -371,8 +361,8 @@ function M.locations_to_items(locations, ctx) vim.fn.bufload(bufnr) unload = bufnr end - context = ts_context({ bufnr = bufnr, pos = item.range }) or '' - log(context) + context = ts_context({ bufnr = bufnr, pos = item.range }) or 'not found' + log(i, context) -- TODO: unload buffers if unload then @@ -426,6 +416,10 @@ function M.locations_to_items(locations, ctx) item.display_filename = filename or item.filename item.call_by = context -- find_ts_func_by_range(funcs, item.range) item.rpath = util.get_relative_path(cwd, gutil.add_pec(item.filename)) + if is_win then + -- windows C: vs c: -- log(item.filename, filename, cwd .. path_sep, path_cur) + item.display_filename = item.rpath or item.display_filename + end width = math.max(width, #item.text) item.symbol_name = M.get_symbol(item.text, item.range) item.lhs = check_lhs(item.text, item.symbol_name) diff --git a/lua/navigator/reference.lua b/lua/navigator/reference.lua index fb2dd91..2083827 100644 --- a/lua/navigator/reference.lua +++ b/lua/navigator/reference.lua @@ -9,12 +9,29 @@ local trace = require('navigator.util').trace -- local lsphelper = require "navigator.lspwrapper" local locations_to_items = lsphelper.locations_to_items +local function order_locations(locations) + table.sort(locations, function(i, j) + if i == nil or j == nil or i.uri == nil or j.uri == nil then + -- log(i, j) + return false + end + if i.uri == j.uri then + if i.range and i.range.start then + return i.range.start.line < j.range.start.line + end + return false + else + return i.uri < j.uri + end + end) + return locations +end local M = {} local ref_view = function(err, locations, ctx, cfg) cfg = cfg or {} local truncate = cfg and cfg.truncate or 20 local opts = {} - trace('arg1', err, ctx, locations) + trace('ref_view', err, ctx, #locations, cfg, locations) -- log(#locations, locations[1]) if ctx.combine then -- wait for both reference and definition LSP request @@ -45,16 +62,16 @@ local ref_view = function(err, locations, ctx, cfg) if references and references.result and #references.result > 0 then local refs = references.result + + order_locations(refs) vim.list_extend(locations, refs) end err = nil - trace(locations) -- lets de-dup first 10 elements. some lsp does not recognize definition and reference difference locations = util.dedup(locations) trace(locations) end - -- log("num", num) - -- log("bfnr", bufnr) + -- log('num bufnr: ', num, bufnr) if err ~= nil then vim.notify( 'lsp ref callback error' .. vim.inspect(err) .. vim.inspect(ctx) .. vim.inspect(locations), @@ -63,12 +80,6 @@ local ref_view = function(err, locations, ctx, cfg) log('ref callback error, lsp may not ready', err, ctx, vim.inspect(locations)) return end - if type(locations) ~= 'table' then - log(locations) - log('ctx', ctx) - vim.notify('incorrect setup' .. vim.inspect(locations), vim.log.levels.WARN) - return - end if locations == nil or vim.tbl_isempty(locations) then vim.notify('References not found', vim.log.levels.INFO) return @@ -76,8 +87,11 @@ local ref_view = function(err, locations, ctx, cfg) ctx.max_items = truncate local items, width, second_part = locations_to_items(locations, ctx) - local thread_items = vim.deepcopy(items) - log('splits: ', #items, #second_part) + local thread_items = {} + if vim.fn.empty(second_part) == 0 then + thread_items = vim.deepcopy(items) + end + log('splits: ', #locations, #items, #second_part) local ft = vim.api.nvim_buf_get_option(ctx.bufnr or 0, 'ft') @@ -114,12 +128,13 @@ local ref_view = function(err, locations, ctx, cfg) -- trace("update items", listview.ctrl.class) local nv_ref_async - nv_ref_async = vim.loop.new_async(vim.schedule_wrap(function() - log('$$$$$$$$ seperate thread... $$$$$$$$') + local uv = vim.uv or vim.loop + nv_ref_async = uv.new_async(vim.schedule_wrap(function() if vim.tbl_isempty(second_part) then return end - ctx.max_items = #second_part + log('$$$$$$$$ --- seperate thread... --- $$$$$$$$') + ctx.max_items = #second_part -- proccess all the rest local items2 = locations_to_items(second_part, ctx) vim.list_extend(thread_items, items2) @@ -128,17 +143,17 @@ local ref_view = function(err, locations, ctx, cfg) log('thread data size', #data) listview.ctrl:on_data_update(data) if nv_ref_async then - vim.loop.close(nv_ref_async) + uv.close(nv_ref_async) else - log('invalid asy', nv_ref_async) + log('invalid ref_async') end end)) vim.defer_fn(function() - vim.loop.new_thread(function(asy) + uv.new_thread(function(asy) asy:send() end, nv_ref_async) - end, 100) + end, 10) return listview, items, width end @@ -173,7 +188,7 @@ local async_ref = function() end end results.definitions = { error = err, result = result, ctx = ctx, config = config } - log(result) + log('number of result', #result) ctx = ctx or {} ctx.results = results ctx.combine = true @@ -199,7 +214,7 @@ end -- a function from smjonas/inc-rename.nvim -- https://github.com/smjonas/inc-rename.nvim/blob/main/lua/inc_rename/init.lua local function fetch_lsp_references(bufnr, params, callback) - local clients = vim.lsp.get_active_clients({ + local clients = vim.lsp.get_clients({ bufnr = bufnr, }) clients = vim.tbl_filter(function(client) diff --git a/lua/navigator/treesitter.lua b/lua/navigator/treesitter.lua index 44e6f7b..4779b49 100644 --- a/lua/navigator/treesitter.lua +++ b/lua/navigator/treesitter.lua @@ -79,7 +79,7 @@ end -- use lsp range to find def function M.find_definition(range, bufnr) if not range or not range.start then - lerr('find_def incorrect range', range) + lerr('find_def incorrect range'..vim.inspect(range)) return end bufnr = bufnr or api.nvim_get_current_buf() @@ -169,12 +169,14 @@ local transform_line = function(line) end function M.ref_context(opts) - if not parsers.has_parser() then + local options = opts or {} + local bufnr = options.bufnr or api.nvim_get_current_buf() + local parser = parsers.get_parser(bufnr) + if not parser then + log('err: ts not loaded ' .. vim.o.ft) return end - local options = opts or {} - local bufnr = options.bufnr or 0 local pos = options.pos if not pos then pos = { start = vim.lsp.util.make_position_params().position } @@ -195,7 +197,7 @@ function M.ref_context(opts) while expr do local line = ts_utils._get_line_for_node(expr, type_patterns, transform_fn, bufnr) - log(line) + log('line', line) if line ~= '' and not vim.tbl_contains(lines, line) then table.insert(lines, 1, line) end @@ -204,11 +206,15 @@ function M.ref_context(opts) break end end + if #lines == 0 then + log('no lines found') + return '' + end local text = table.concat(lines, separator) local text_len = #text if text_len > indicator_size then - local str = text:sub(1, text_len) + local str = text:sub(1, text_len) -- copy string return util.sub_match(str) end diff --git a/lua/navigator/util.lua b/lua/navigator/util.lua index 1181073..6c09782 100644 --- a/lua/navigator/util.lua +++ b/lua/navigator/util.lua @@ -8,9 +8,11 @@ local guihua = require('guihua.util') local nvim_0_8 local vfn = vim.fn local api = vim.api +local uv = vim.uv or vim.loop +local os_name = uv.os_uname().sysname +local is_win = os_name:find('Windows') or os_name:find('MINGW') M.path_sep = function() - local is_win = vim.loop.os_uname().sysname:find('Windows') if is_win then return '\\' else @@ -21,7 +23,6 @@ end local path_sep = M.path_sep() M.path_cur = function() - local is_win = vim.loop.os_uname().sysname:find('Windows') if is_win then return '.\\' else @@ -140,22 +141,28 @@ end function M.get_relative_path(base_path, my_path) M.log('rel path', base_path, my_path) + base_path = string.lower(base_path) + my_path = string.lower(my_path) local base_data = getDir(base_path) if base_data == nil then + M.log('base data is nil') return end local my_data = getDir(my_path) - if my_data == nil then + if vim.fn.empty(my_data) == 1 then + M.log('my data is nil', my_path) return end local base_len = #base_data local my_len = #my_data if base_len > my_len then + M.log('incorrect dir format: base data', base_data, 'my data', my_data) return my_path end if base_data[1] ~= my_data[1] then + M.log('base data is not same', base_data[1], my_data[1]) return my_path end @@ -277,9 +284,10 @@ function M.open_log() local path = vim.lsp.get_log_path() vim.cmd('edit ' .. path) end - -function table.pack(...) - return { n = select('#', ...), ... } +if not table.pack then + table.pack = function(...) + return { n = select('#', ...), ... } + end end function M.show(...) local string = '' @@ -481,10 +489,7 @@ function M.info(msg) end function M.dedup(locations) - local m = 10 - if m > #locations then - m = #locations - end + local m = math.min(10, #locations) -- dedup first 10 elements local dict = {} local del = {} for i = 1, m, 1 do @@ -553,7 +558,7 @@ function M.sub_match(str) if j % 2 == 1 then str = str .. [[']] end - str = str .. '' + str = str .. '󰇘' return str end