add multiple symbol highlight

neovim_0_5
ray-x 3 years ago
parent 1546b6a604
commit 6a15e6838d

@ -56,6 +56,8 @@ implementation.
- FZY search with Lua-JIT - FZY search with Lua-JIT
- LSP multiple symbol highlight and jump between reference
- Better navigation for diagnostic errors, Navigate through all files/buffers that contain errors/warnings - Better navigation for diagnostic errors, Navigate through all files/buffers that contain errors/warnings
- Grouping references/implementation/incoming/outgoing based on file names. - Grouping references/implementation/incoming/outgoing based on file names.
@ -258,6 +260,9 @@ Pls check the first part of README
![workspace symbol](https://github.com/ray-x/files/blob/master/img/navigator/workspace_symbol.gif?raw=true) ![workspace symbol](https://github.com/ray-x/files/blob/master/img/navigator/workspace_symbol.gif?raw=true)
### highlight document symbol and jump between reference
![multiple_symbol_hi3](https://user-images.githubusercontent.com/1681295/120067627-f9f80680-c0bf-11eb-9216-18e5c8547f59.gif)
# Current symbol highlight and jump backward/forward between symbols # Current symbol highlight and jump backward/forward between symbols
Document highlight provided by LSP. Document highlight provided by LSP.

@ -1,7 +1,127 @@
local util = require "navigator.util" local util = require "navigator.util"
local log = util.log local log = util.log
local trace = util.trace
local api = vim.api local api = vim.api
local references = {} local references = {}
_NG_hi_list = {}
_NG_current_symbol = ""
_NG_ref_hi_idx = 1
-- extract symbol from cursor
local function get_symbol()
local currentWord = vim.fn.expand('<cword>')
return currentWord
end
local function add_locs(bufnr, result)
local symbol = get_symbol()
if #result < 1 then
return
end
symbol = string.format("%s_%i_%i_%i", symbol, bufnr, result[1].range.start.line,
result[1].range.start.character)
if _NG_hi_list[symbol] == nil then
_NG_hi_list[symbol] = {range = {}}
end
if _NG_hi_list[symbol] ~= nil then
log("already added", symbol)
_NG_hi_list[symbol].range = {}
-- vim.fn.matchdelete(hid)
end
trace("add ", symbol)
_NG_hi_list[symbol].range = result
_NG_current_symbol = symbol
end
local function nohl()
for key, value in pairs(_NG_hi_list) do
if value.hi_ids ~= nil then
for _, v in ipairs(value.hi_ids) do
log("delete", v)
vim.fn.matchdelete(v)
end
_NG_hi_list[key].hi_ids = nil
end
end
end
local function hi_symbol()
local symbol_wd = get_symbol()
local symbol = _NG_current_symbol
if string.find(symbol, symbol_wd) == nil then
vim.lsp.buf.document_highlight()
symbol = _NG_current_symbol
end
if symbol == nil or symbol == "" then
log("nil symbol")
return
end
_NG_ref_hi_idx = _NG_ref_hi_idx + 1
if _NG_ref_hi_idx > 6 then -- 6 magic number for colors
_NG_ref_hi_idx = 1
end
local range = _NG_hi_list[symbol].range or {}
if _NG_hi_list[symbol].hi_ids ~= nil then
for _, value in ipairs(_NG_hi_list[symbol].hi_ids) do
log("delete", value)
vim.fn.matchdelete(value)
end
_NG_hi_list[symbol].hi_ids = nil
return
end
local cur_pos = vim.fn.getpos('.')
_NG_hi_list[symbol].hi_ids = {}
local totalref = #range
local cmd = string.format("%s/\\<%s\\>//gn", "%s", symbol_wd)
local total_match = 0
local match_result = vim.api.nvim_exec(cmd, true)
local p = match_result:find(" match")
vim.cmd("nohl")
vim.fn.setpos('.', cur_pos)
if p ~= nil then
p = match_result:sub(1, p)
total_match = tonumber(p)
end
if total_match == totalref then -- same number as matchpos
log(total_match, "use matchadd()")
local k = range[1].kind
local hi_name = string.format("NGHiReference_%i_%i", _NG_ref_hi_idx, k)
local m = string.format("\\<%s\\>", symbol_wd)
local r = vim.fn.matchadd(hi_name, m, 20)
trace("hi id", m, hi_name, r)
table.insert(_NG_hi_list[symbol].hi_ids, r)
--
-- vim.fn.matchdelete(r)
else
for _, value in ipairs(range) do
local k = value.kind
local l = value.range.start.line + 1
local el = value.range['end'].line + 1
local cs = value.range.start.character + 1
local ecs = value.range['end'].character + 1
if el ~= l and cs == 1 and ecs > 1 then
l = el
end
local w = value.range['end'].character - value.range.start.character
local hi_name = string.format("NGHiReference_%i_%i", _NG_ref_hi_idx, k)
log(hi_name, {l, cs, w})
local m = vim.fn.matchaddpos(hi_name, {{l, cs, w}}, 10)
table.insert(_NG_hi_list[symbol].hi_ids, m)
end
end
-- clean the _NG_hi_list
for key, value in pairs(_NG_hi_list) do
if value.hi_ids == nil then
_NG_hi_list[key] = nil
end
end
-- log(_NG_hi_list)
end
-- returns r1 < r2 based on start of range -- returns r1 < r2 based on start of range
local function before(r1, r2) local function before(r1, r2)
@ -71,10 +191,14 @@ local function goto_adjent_reference(opt)
vim.api.nvim_win_set_cursor(0, {next.start.line + 1, next.start.character}) vim.api.nvim_win_set_cursor(0, {next.start.line + 1, next.start.character})
return next return next
end end
-- autocmd ColorScheme *
-- \ hi default LspReferenceRead cterm=bold gui=Bold ctermbg=yellow guifg=yellow guibg=purple4 | local function cmd_nohl()
-- \ hi default LspReferenceText cterm=bold gui=Bold ctermbg=red guifg=SlateBlue guibg=MidnightBlue | local cl = vim.trim(vim.fn.getcmdline())
-- \ hi default LspReferenceWrite cterm=bold gui=Bold,Italic ctermbg=red guifg=DarkSlateBlue guibg=MistyRose if #cl > 3 and ('nohlsearch'):match(cl) then
vim.schedule(nohl)
end
end
local function documentHighlight() local function documentHighlight()
api.nvim_exec([[ api.nvim_exec([[
autocmd ColorScheme * | autocmd ColorScheme * |
@ -89,10 +213,15 @@ local function documentHighlight()
augroup END augroup END
]], false) ]], false)
vim.lsp.handlers["textDocument/documentHighlight"] = vim.lsp.handlers["textDocument/documentHighlight"] =
function(_, _, result, _, bufnr) function(err, _, result, _, bufnr)
if err then
print(err)
return
end
if not result then if not result then
return return
end end
trace("dochl", result)
bufnr = api.nvim_get_current_buf() bufnr = api.nvim_get_current_buf()
vim.lsp.util.buf_clear_references(bufnr) vim.lsp.util.buf_clear_references(bufnr)
vim.lsp.util.buf_highlight_references(bufnr, result) vim.lsp.util.buf_highlight_references(bufnr, result)
@ -105,11 +234,15 @@ local function documentHighlight()
return before(a.range, b.range) return before(a.range, b.range)
end) end)
references[bufnr] = result references[bufnr] = result
add_locs(bufnr, result)
end end
end end
return { return {
documentHighlight = documentHighlight, documentHighlight = documentHighlight,
goto_adjent_reference = goto_adjent_reference, goto_adjent_reference = goto_adjent_reference,
handle_document_highlight = handle_document_highlight handle_document_highlight = handle_document_highlight,
hi_symbol = hi_symbol,
nohl = nohl,
cmd_nohl = cmd_nohl
} }

@ -151,6 +151,28 @@ function M.new_list_view(opts)
offset_y = offset_y + 1 -- need to check this out offset_y = offset_y + 1 -- need to check this out
end end
local function idx(data_list, pos)
-- first check if fzy is set
local fzy_on = false
for _, value in ipairs(data_list) do
if value.fzy ~= nil then
fzy_on = true
break
end
end
if fzy_on == true then
local i = 1
for _, value in ipairs(data_list) do
if value.fzy ~= nil then
if i == pos then
return value
end
i = i + 1
end
end
end
return data[pos]
end
return ListView:new({ return ListView:new({
loc = loc, loc = loc,
prompt = prompt, prompt = prompt,
@ -166,7 +188,8 @@ function M.new_list_view(opts)
if pos == 0 then if pos == 0 then
pos = 1 pos = 1
end end
local l = data[pos] local l = idx(data, pos) -- bug it not work with fzy filter
log(data)
if l.filename ~= nil then if l.filename ~= nil then
trace("openfile ", l.filename, l.lnum, l.col) trace("openfile ", l.filename, l.lnum, l.col)
util.open_file_at(l.filename, l.lnum, l.col) util.open_file_at(l.filename, l.lnum, l.col)
@ -176,7 +199,9 @@ function M.new_list_view(opts)
if pos == 0 then if pos == 0 then
pos = 1 pos = 1
end end
local l = data[pos]
local l = idx(data, pos) -- bug it not work with fzy filter
log(data)
trace("on move", pos, l) trace("on move", pos, l)
trace("on move", pos, l.text or l, l.uri, l.filename) trace("on move", pos, l.text or l, l.uri, l.filename)
-- todo fix -- todo fix

@ -1,7 +1,7 @@
-- todo allow config passed in -- todo allow config passed in
local log = require"navigator.util".log local log = require"navigator.util".log
local trace = require"navigator.util".trace local trace = require"navigator.util".trace
local uv = vim.loop
_Loading = false _Loading = false
_LoadedClients = {} _LoadedClients = {}
@ -68,6 +68,23 @@ library[vim.fn.expand("$VIMRUNTIME/lua/vim")] = true
library[vim.fn.expand("$VIMRUNTIME/lua/vim/lsp")] = true library[vim.fn.expand("$VIMRUNTIME/lua/vim/lsp")] = true
-- [vim.fn.expand("~/repos/nvim/lua")] = true -- [vim.fn.expand("~/repos/nvim/lua")] = true
-- TODO remove onece PR #944 merged to lspconfig
local is_windows = uv.os_uname().version:match("Windows")
local path_sep = is_windows and "\\" or "/"
local strip_dir_pat = path_sep .. "([^" .. path_sep .. "]+)$"
local strip_sep_pat = path_sep .. "$"
local dirname = function(path)
if not path or #path == 0 then
return
end
local result = path:gsub(strip_sep_pat, ""):gsub(strip_dir_pat, "")
if #result == 0 then
return "/"
end
return result
end
-- TODO end
local setups = { local setups = {
gopls = { gopls = {
on_attach = on_attach, on_attach = on_attach,
@ -101,7 +118,7 @@ local setups = {
} }
}, },
root_dir = function(fname) root_dir = function(fname)
return util.root_pattern("go.mod", ".git")(fname) or util.path.dirname(fname) return util.root_pattern("go.mod", ".git")(fname) or dirname(fname) -- util.path.dirname(fname)
end end
}, },
clangd = { clangd = {

@ -3,10 +3,18 @@ local api = vim.api
-- lsp sign          ﮻         ﯭ        ﳀ   -- lsp sign          ﮻         ﯭ        ﳀ  
function M.diagnositc_config_sign() function M.diagnositc_config_sign()
vim.fn.sign_define('LspDiagnosticsSignError', {text='', texthl='LspDiagnosticsSignError',linehl='', numhl=''}) vim.fn.sign_define('LspDiagnosticsSignError',
vim.fn.sign_define('LspDiagnosticsSignWarning', {text='', texthl='LspDiagnosticsSignWarning', linehl='', numhl=''}) {text = '', texthl = 'LspDiagnosticsSignError', linehl = '', numhl = ''})
vim.fn.sign_define('LspDiagnosticsSignInformation', {text='', texthl='LspDiagnosticsSignInformation', linehl='', numhl=''}) vim.fn.sign_define('LspDiagnosticsSignWarning',
vim.fn.sign_define('LspDiagnosticsSignHint', {text='💡', texthl='LspDiagnosticsSignHint', linehl='', numhl=''}) {text = '', texthl = 'LspDiagnosticsSignWarning', linehl = '', numhl = ''})
vim.fn.sign_define('LspDiagnosticsSignInformation', {
text = '',
texthl = 'LspDiagnosticsSignInformation',
linehl = '',
numhl = ''
})
vim.fn.sign_define('LspDiagnosticsSignHint',
{text = '💡', texthl = 'LspDiagnosticsSignHint', linehl = '', numhl = ''})
end end
function M.add_highlight() function M.add_highlight()
@ -18,6 +26,19 @@ function M.add_highlight()
api.nvim_command("hi! link LspDiagnosticsUnderlineHint SpellRare") api.nvim_command("hi! link LspDiagnosticsUnderlineHint SpellRare")
api.nvim_command("hi def link DefinitionPreviewTitle Title") api.nvim_command("hi def link DefinitionPreviewTitle Title")
local colors = {
{'#aefe00', '#aede00', '#aebe00', '#4e7efe'}, {'#ff00e0', '#df00e0', '#af00e0', '#fedefe'},
{'#1000ef', '#2000df', '#2000cf', '#f0f040'}, {'#d8a8a3', '#c8a8a3', '#b8a8a3', '#4e2c33'},
{'#ffa724', '#efa024', '#dfa724', '#0040ff'}, {'#afdc2b', '#09dc4b', '#08d04b', '#ef4f8f'}
}
for i = 1, #colors do
for j = 1, 3 do
local cmd = string.format("hi! default NGHiReference_%i_%i guibg=%s guifg=%s ", i, j,
colors[i][j], colors[i][4])
vim.cmd(cmd)
end
end
end end
return M return M

@ -27,7 +27,8 @@ local key_maps = {
{key = "]d", func = "diagnostic.goto_next()"}, {key = "[d", func = "diagnostic.goto_prev()"}, {key = "]d", func = "diagnostic.goto_next()"}, {key = "[d", func = "diagnostic.goto_prev()"},
{key = "]r", func = "require('navigator.treesitter').goto_next_usage()"}, {key = "]r", func = "require('navigator.treesitter').goto_next_usage()"},
{key = "[r", func = "require('navigator.treesitter').goto_previous_usage()"}, {key = "[r", func = "require('navigator.treesitter').goto_previous_usage()"},
{key = "<C-LeftMouse>", func = "definition()"}, {key = "g<LeftMouse>", func = "implementation()"} {key = "<C-LeftMouse>", func = "definition()"}, {key = "g<LeftMouse>", func = "implementation()"},
{key = "<Leader>k", func = "require('navigator.dochighlight').hi_symbol()"}
} }
local function set_mapping(user_opts) local function set_mapping(user_opts)
@ -99,6 +100,15 @@ local function set_mapping(user_opts)
end end
end end
local function autocmd(user_opts)
vim.api.nvim_exec([[
aug NavigatorAu
au!
au CmdlineLeave : lua require('navigator.dochighlight').cmd_nohl()
aug END
]], false)
end
local function set_event_handler(user_opts) local function set_event_handler(user_opts)
user_opts = user_opts or {} user_opts = user_opts or {}
local file_types = local file_types =
@ -129,6 +139,7 @@ function M.setup(user_opts)
set_mapping(user_opts) set_mapping(user_opts)
end end
autocmd(user_opts)
set_event_handler(user_opts) set_event_handler(user_opts)
local cap = user_opts.cap or vim.lsp.protocol.make_client_capabilities() local cap = user_opts.cap or vim.lsp.protocol.make_client_capabilities()

@ -122,8 +122,8 @@ function M.prepare_for_render(items, opts)
if item.definition then if item.definition then
ts_report = ts_report .. '🦕 ' ts_report = ts_report .. '🦕 '
end end
local header_len = #ts_report + 2 -- magic number 2 local header_len = #ts_report + 4 -- magic number 2
trace(ts_report) log(ts_report, header_len)
item.text = item.text:gsub('%s*[%[%(%{]*%s*$', '') item.text = item.text:gsub('%s*[%[%(%{]*%s*$', '')
if item.call_by ~= nil and #item.call_by > 0 then if item.call_by ~= nil and #item.call_by > 0 then

@ -75,7 +75,9 @@ function M.workspace_symbols(opts)
end end
function M.document_symbol_handler(err, _, result, _, bufnr) function M.document_symbol_handler(err, _, result, _, bufnr)
if err then print(bufnr, "failed to get document symbol") end if err then
print(bufnr, "failed to get document symbol")
end
if not result or vim.tbl_isempty(result) then if not result or vim.tbl_isempty(result) then
print(bufnr, "symbol not found for buf") print(bufnr, "symbol not found for buf")
@ -96,10 +98,12 @@ function M.document_symbol_handler(err, _, result, _, bufnr)
item.uri = uri item.uri = uri
item.selectionRange = result[i].selectionRange item.selectionRange = result[i].selectionRange
item.detail = result[i].detail or "" item.detail = result[i].detail or ""
if item.detail == "()" then item.detail = "func" end if item.detail == "()" then
item.detail = "func"
end
item.lnum = result[i].range.start.line + 1 item.lnum = result[i].range.start.line + 1
item.text = "[" .. kind .. "]" .. item.detail .. " " .. item.name item.text = "[" .. kind .. "]" .. item.name .. " " .. item.detail
item.filename = fname item.filename = fname
@ -116,7 +120,7 @@ function M.document_symbol_handler(err, _, result, _, bufnr)
child.uri = uri child.uri = uri
child.lnum = c.range.start.line + 1 child.lnum = c.range.start.line + 1
child.detail = c.detail or "" child.detail = c.detail or ""
child.text = "  [" .. ckind .. "] " .. child.detail .. " " .. child.name child.text = "  [" .. ckind .. "] " .. child.name .. " " .. child.detail
table.insert(locations, child) table.insert(locations, child)
end end
end end
@ -149,7 +153,9 @@ function M.document_symbol_handler(err, _, result, _, bufnr)
end end
function M.workspace_symbol_handler(err, _, result, _, bufnr) function M.workspace_symbol_handler(err, _, result, _, bufnr)
if err then print(bufnr, "failed to get workspace symbol") end if err then
print(bufnr, "failed to get workspace symbol")
end
if not result or vim.tbl_isempty(result) then if not result or vim.tbl_isempty(result) then
print(bufnr, "symbol not found for buf") print(bufnr, "symbol not found for buf")
return return

Loading…
Cancel
Save