|
|
|
@ -1,16 +1,17 @@
|
|
|
|
|
local gui = require "navigator.gui"
|
|
|
|
|
local gui = require('navigator.gui')
|
|
|
|
|
local diagnostic_list = {}
|
|
|
|
|
local diagnostic = vim.diagnostic or vim.lsp.diagnostic
|
|
|
|
|
-- local hide = diagnostic.hide or diagnostic.clear
|
|
|
|
|
_NG_VT_DIAG_NS = vim.api.nvim_create_namespace("navigator_lua_diag")
|
|
|
|
|
local util = require "navigator.util"
|
|
|
|
|
_NG_VT_DIAG_NS = vim.api.nvim_create_namespace('navigator_lua_diag')
|
|
|
|
|
local util = require('navigator.util')
|
|
|
|
|
local log = util.log
|
|
|
|
|
local trace = require"guihua.log".trace
|
|
|
|
|
local trace = require('guihua.log').trace
|
|
|
|
|
-- trace = log
|
|
|
|
|
local error = util.error
|
|
|
|
|
local path_sep = require"navigator.util".path_sep()
|
|
|
|
|
local mk_handler = require"navigator.util".mk_handler
|
|
|
|
|
local path_cur = require"navigator.util".path_cur()
|
|
|
|
|
local path_sep = require('navigator.util').path_sep()
|
|
|
|
|
local mk_handler = require('navigator.util').mk_handler
|
|
|
|
|
local path_cur = require('navigator.util').path_cur()
|
|
|
|
|
local empty = util.empty
|
|
|
|
|
diagnostic_list[vim.bo.filetype] = {}
|
|
|
|
|
local function clear_diag_VT(bufnr) -- important for clearing out when no more errors
|
|
|
|
|
log(bufnr, _NG_VT_DIAG_NS)
|
|
|
|
@ -28,21 +29,24 @@ if vim.diagnostic then
|
|
|
|
|
Error = vim.diagnostic.severity.ERROR,
|
|
|
|
|
Warning = vim.diagnostic.severity.WARN,
|
|
|
|
|
Info = vim.diagnostic.severity.Info,
|
|
|
|
|
Hint = vim.diagnostic.severity.Hint
|
|
|
|
|
Hint = vim.diagnostic.severity.Hint,
|
|
|
|
|
}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local function get_count(bufnr, level)
|
|
|
|
|
if vim.diagnostic ~= nil then
|
|
|
|
|
return #diagnostic.get(bufnr, {severity = diag_map[level]})
|
|
|
|
|
return #diagnostic.get(bufnr, { severity = diag_map[level] })
|
|
|
|
|
else
|
|
|
|
|
return diagnostic.get_count(bufnr, level)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local function error_marker(result, ctx, config)
|
|
|
|
|
if _NgConfigValues.lsp.diagnostic_scrollbar_sign == nil or _NgConfigValues.lsp.diagnostic_scrollbar_sign == {}
|
|
|
|
|
or _NgConfigValues.lsp.diagnostic_scrollbar_sign == false then -- not enabled or already shown
|
|
|
|
|
if
|
|
|
|
|
_NgConfigValues.lsp.diagnostic_scrollbar_sign == nil
|
|
|
|
|
or empty(_NgConfigValues.lsp.diagnostic_scrollbar_sign)
|
|
|
|
|
or _NgConfigValues.lsp.diagnostic_scrollbar_sign == false
|
|
|
|
|
then -- not enabled or already shown
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
@ -60,14 +64,13 @@ local function error_marker(result, ctx, config)
|
|
|
|
|
local fname = vim.api.nvim_buf_get_name(bufnr)
|
|
|
|
|
local uri = vim.uri_from_fname(fname)
|
|
|
|
|
if uri ~= result.uri then
|
|
|
|
|
log("not same buf", ctx, result.uri, bufnr, vim.fn.bufnr())
|
|
|
|
|
log('not same buf', ctx, result.uri, bufnr, vim.fn.bufnr())
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if not vim.api.nvim_buf_is_loaded(bufnr) then
|
|
|
|
|
log("buf not loaded", bufnr)
|
|
|
|
|
log('buf not loaded', bufnr)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
trace('schedule callback', result, ctx, config)
|
|
|
|
@ -76,7 +79,7 @@ local function error_marker(result, ctx, config)
|
|
|
|
|
if result == nil or result.diagnostics == nil or #result.diagnostics == 0 then
|
|
|
|
|
local diag_cnt = get_count(bufnr, [[Error]]) + get_count(bufnr, [[Warning]])
|
|
|
|
|
if diag_cnt == 0 and _NG_VT_DIAG_NS ~= nil then
|
|
|
|
|
log("great no errors")
|
|
|
|
|
log('great no errors')
|
|
|
|
|
vim.api.nvim_buf_clear_namespace(bufnr, _NG_VT_DIAG_NS, 0, -1)
|
|
|
|
|
end
|
|
|
|
|
return
|
|
|
|
@ -92,13 +95,13 @@ local function error_marker(result, ctx, config)
|
|
|
|
|
|
|
|
|
|
local stats = vim.api.nvim_list_uis()[1]
|
|
|
|
|
-- local wwidth = stats.width;
|
|
|
|
|
local wheight = stats.height;
|
|
|
|
|
local wheight = stats.height
|
|
|
|
|
|
|
|
|
|
if total_num <= wheight then
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
if _NG_VT_DIAG_NS == nil then
|
|
|
|
|
_NG_VT_DIAG_NS = vim.api.nvim_create_namespace("navigator_lua_diag")
|
|
|
|
|
_NG_VT_DIAG_NS = vim.api.nvim_create_namespace('navigator_lua_diag')
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local pos = {}
|
|
|
|
@ -106,7 +109,7 @@ local function error_marker(result, ctx, config)
|
|
|
|
|
|
|
|
|
|
for i, _ in ipairs(diags) do
|
|
|
|
|
if not diags[i].range then
|
|
|
|
|
diags[i].range = {start = {line = diags[i].lnum}}
|
|
|
|
|
diags[i].range = { start = { line = diags[i].lnum } }
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
@ -117,7 +120,7 @@ local function error_marker(result, ctx, config)
|
|
|
|
|
for _, diag in pairs(result.diagnostics) do
|
|
|
|
|
local p
|
|
|
|
|
if not diag.range then
|
|
|
|
|
diag.range = {start = {line = diag.lnum}}
|
|
|
|
|
diag.range = { start = { line = diag.lnum } }
|
|
|
|
|
end
|
|
|
|
|
if diag.range and diag.range.start and diag.range.start.line then
|
|
|
|
|
p = diag.range.start.line
|
|
|
|
@ -127,17 +130,16 @@ local function error_marker(result, ctx, config)
|
|
|
|
|
if pos[#pos] == bar then
|
|
|
|
|
bar = _NgConfigValues.lsp.diagnostic_scrollbar_sign[3]
|
|
|
|
|
end
|
|
|
|
|
pos[#pos] = {line = p, sign = bar, severity = math.min(diag.severity, pos[#pos].severity)}
|
|
|
|
|
pos[#pos] = { line = p, sign = bar, severity = math.min(diag.severity, pos[#pos].severity) }
|
|
|
|
|
else
|
|
|
|
|
table.insert(pos,
|
|
|
|
|
{
|
|
|
|
|
table.insert(pos, {
|
|
|
|
|
line = p,
|
|
|
|
|
sign = _NgConfigValues.lsp.diagnostic_scrollbar_sign[1],
|
|
|
|
|
severity = diag.severity
|
|
|
|
|
severity = diag.severity,
|
|
|
|
|
})
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
trace("pos, line:", p, diag.severity, diag.range)
|
|
|
|
|
trace('pos, line:', p, diag.severity, diag.range)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if not vim.tbl_isempty(pos) then
|
|
|
|
@ -145,38 +147,41 @@ local function error_marker(result, ctx, config)
|
|
|
|
|
end
|
|
|
|
|
for i, s in pairs(pos) do
|
|
|
|
|
local hl = 'ErrorMsg'
|
|
|
|
|
if type(s.severity) == "number" then
|
|
|
|
|
if type(s.severity) == 'number' then
|
|
|
|
|
if s.severity == 2 then
|
|
|
|
|
hl = 'WarningMsg'
|
|
|
|
|
elseif s.severity >= 3 then
|
|
|
|
|
hl = 'DiagnosticInfo'
|
|
|
|
|
end
|
|
|
|
|
elseif type(s.severity) == "string" then
|
|
|
|
|
if s.severity:lower() == "warn" then
|
|
|
|
|
hl = "WarningMsg"
|
|
|
|
|
elseif type(s.severity) == 'string' then
|
|
|
|
|
if s.severity:lower() == 'warn' then
|
|
|
|
|
hl = 'WarningMsg'
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
local l = s.line + first_line
|
|
|
|
|
if l > total_num then
|
|
|
|
|
l = total_num
|
|
|
|
|
end
|
|
|
|
|
trace("add pos", s, bufnr)
|
|
|
|
|
|
|
|
|
|
vim.api.nvim_buf_set_extmark(bufnr, _NG_VT_DIAG_NS, l, -1,
|
|
|
|
|
{virt_text = {{s.sign, hl}}, virt_text_pos = 'right_align'})
|
|
|
|
|
trace('add pos', s, bufnr)
|
|
|
|
|
|
|
|
|
|
vim.api.nvim_buf_set_extmark(
|
|
|
|
|
bufnr,
|
|
|
|
|
_NG_VT_DIAG_NS,
|
|
|
|
|
l,
|
|
|
|
|
-1,
|
|
|
|
|
{ virt_text = { { s.sign, hl } }, virt_text_pos = 'right_align' }
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
end, 10) -- defer in 10ms
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local update_err_marker_async = function()
|
|
|
|
|
local debounce = require'navigator.debounce'.debounce_trailing
|
|
|
|
|
local debounce = require('navigator.debounce').debounce_trailing
|
|
|
|
|
return debounce(400, error_marker)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local diag_hdlr = mk_handler(function(err, result, ctx, config)
|
|
|
|
|
|
|
|
|
|
require"navigator.lspclient.highlight".diagnositc_config_sign()
|
|
|
|
|
require('navigator.lspclient.highlight').diagnositc_config_sign()
|
|
|
|
|
if err ~= nil then
|
|
|
|
|
log(err, config, result)
|
|
|
|
|
return
|
|
|
|
@ -184,7 +189,7 @@ local diag_hdlr = mk_handler(function(err, result, ctx, config)
|
|
|
|
|
|
|
|
|
|
local mode = vim.api.nvim_get_mode().mode
|
|
|
|
|
if mode ~= 'n' and config.update_in_insert == false then
|
|
|
|
|
log("skip sign update in insert mode")
|
|
|
|
|
log('skip sign update in insert mode')
|
|
|
|
|
end
|
|
|
|
|
local cwd = vim.loop.cwd()
|
|
|
|
|
local ft = vim.bo.filetype
|
|
|
|
@ -202,15 +207,15 @@ local diag_hdlr = mk_handler(function(err, result, ctx, config)
|
|
|
|
|
trace(err, result, ctx, config)
|
|
|
|
|
vim.lsp.diagnostic.on_publish_diagnostics(err, result, ctx, config)
|
|
|
|
|
else
|
|
|
|
|
log("old version of lsp nvim 050")
|
|
|
|
|
log('old version of lsp nvim 050')
|
|
|
|
|
vim.lsp.diagnostic.on_publish_diagnostics(err, _, result, ctx.client_id, _, config)
|
|
|
|
|
end
|
|
|
|
|
local uri = result.uri
|
|
|
|
|
|
|
|
|
|
local diag_cnt = get_count(bufnr, [[Error]]) + get_count(bufnr, [[Warning]])
|
|
|
|
|
|
|
|
|
|
if result.diagnostics == {} and diag_cnt > 0 then
|
|
|
|
|
log("no result? ", diag_cnt)
|
|
|
|
|
if empty(result.diagnostics) and diag_cnt > 0 then
|
|
|
|
|
log('no result? ', diag_cnt)
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
-- trace("diag: ", mode, result, ctx, config)
|
|
|
|
@ -253,11 +258,11 @@ local diag_hdlr = mk_handler(function(err, result, ctx, config)
|
|
|
|
|
end
|
|
|
|
|
local pos = v.range.start
|
|
|
|
|
local row = pos.line
|
|
|
|
|
local line = (vim.api.nvim_buf_get_lines(bufnr1, row, row + 1, false) or {""})[1]
|
|
|
|
|
local line = (vim.api.nvim_buf_get_lines(bufnr1, row, row + 1, false) or { '' })[1]
|
|
|
|
|
if line ~= nil then
|
|
|
|
|
item.text = head .. line .. _NgConfigValues.icons.diagnostic_head_description .. v.message
|
|
|
|
|
else
|
|
|
|
|
error("diagnostic result empty line", v, row, bufnr1)
|
|
|
|
|
error('diagnostic result empty line', v, row, bufnr1)
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
item.text = head .. _NgConfigValues.icons.diagnostic_head_description .. v.message
|
|
|
|
@ -268,7 +273,7 @@ local diag_hdlr = mk_handler(function(err, result, ctx, config)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if v.releated_lnum then
|
|
|
|
|
item.text = item.text .. ":" .. tostring(item.releated_lnum)
|
|
|
|
|
item.text = item.text .. ':' .. tostring(item.releated_lnum)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
table.insert(item_list, item)
|
|
|
|
@ -286,15 +291,14 @@ local diag_hdlr = mk_handler(function(err, result, ctx, config)
|
|
|
|
|
local marker = update_err_marker_async()
|
|
|
|
|
marker(result, ctx, config)
|
|
|
|
|
else
|
|
|
|
|
trace("great, no diag errors")
|
|
|
|
|
trace('great, no diag errors')
|
|
|
|
|
vim.api.nvim_buf_clear_namespace(0, _NG_VT_DIAG_NS, 0, -1)
|
|
|
|
|
_NG_VT_DIAG_NS = nil
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
local diag_hdlr_async = function()
|
|
|
|
|
local debounce = require'navigator.debounce'.debounce_trailing
|
|
|
|
|
local debounce = require('navigator.debounce').debounce_trailing
|
|
|
|
|
return debounce(100, diag_hdlr)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
@ -303,12 +307,12 @@ local diagnostic_cfg = {
|
|
|
|
|
-- Enable underline, use default values
|
|
|
|
|
underline = true,
|
|
|
|
|
-- Enable virtual text, override spacing to 3 (prevent overlap)
|
|
|
|
|
virtual_text = {spacing = 3, prefix = _NgConfigValues.icons.diagnostic_virtual_text},
|
|
|
|
|
virtual_text = { spacing = 3, prefix = _NgConfigValues.icons.diagnostic_virtual_text },
|
|
|
|
|
-- Use a function to dynamically turn signs off
|
|
|
|
|
-- and on, using buffer local variables
|
|
|
|
|
signs = true,
|
|
|
|
|
update_in_insert = _NgConfigValues.lsp.diagnostic_update_in_insert or false,
|
|
|
|
|
severity_sort = {reverse = true}
|
|
|
|
|
severity_sort = { reverse = true },
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if _NgConfigValues.lsp.diagnostic_virtual_text == false then
|
|
|
|
@ -351,10 +355,10 @@ M.show_buf_diagnostics = function()
|
|
|
|
|
if #display_items > 0 then
|
|
|
|
|
local listview = gui.new_list_view({
|
|
|
|
|
items = display_items,
|
|
|
|
|
api = _NgConfigValues.icons.diagnostic_file .. _NgConfigValues.icons.diagnostic_head .. " Diagnostic ",
|
|
|
|
|
enable_preview_edit = true
|
|
|
|
|
api = _NgConfigValues.icons.diagnostic_file .. _NgConfigValues.icons.diagnostic_head .. ' Diagnostic ',
|
|
|
|
|
enable_preview_edit = true,
|
|
|
|
|
})
|
|
|
|
|
trace("new buffer", listview.bufnr)
|
|
|
|
|
trace('new buffer', listview.bufnr)
|
|
|
|
|
vim.api.nvim_buf_add_highlight(listview.bufnr, -1, 'Title', 0, 0, -1)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
@ -362,15 +366,14 @@ end
|
|
|
|
|
|
|
|
|
|
-- set loc list win
|
|
|
|
|
M.set_diag_loclist = function()
|
|
|
|
|
|
|
|
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
|
|
|
local diag_cnt = get_count(bufnr, [[Error]]) + get_count(bufnr, [[Warning]])
|
|
|
|
|
if diag_cnt == 0 then
|
|
|
|
|
log("great, no errors!")
|
|
|
|
|
log('great, no errors!')
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
local clients = vim.lsp.buf_get_clients(0)
|
|
|
|
|
local cfg = {open = diag_cnt > 0}
|
|
|
|
|
local cfg = { open = diag_cnt > 0 }
|
|
|
|
|
for _, client in pairs(clients) do
|
|
|
|
|
cfg.client_id = client['id']
|
|
|
|
|
break
|
|
|
|
@ -386,68 +389,69 @@ M.set_diag_loclist = function()
|
|
|
|
|
diagnostic.setloclist(cfg)
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
vim.cmd("lclose")
|
|
|
|
|
vim.cmd('lclose')
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- TODO: callback when scroll
|
|
|
|
|
function M.update_err_marker()
|
|
|
|
|
trace("update err marker", _NG_VT_DIAG_NS)
|
|
|
|
|
trace('update err marker', _NG_VT_DIAG_NS)
|
|
|
|
|
if _NG_VT_DIAG_NS == nil then
|
|
|
|
|
-- nothing to update
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
|
|
|
|
|
|
|
|
local diag_cnt = get_count(bufnr, [[Error]]) + get_count(bufnr, [[Warning]]) + get_count(bufnr, [[Info]])
|
|
|
|
|
+ get_count(bufnr, [[Hint]])
|
|
|
|
|
local diag_cnt = get_count(bufnr, [[Error]])
|
|
|
|
|
+ get_count(bufnr, [[Warning]])
|
|
|
|
|
+ get_count(bufnr, [[Info]])
|
|
|
|
|
+ get_count(bufnr, [[Hint]])
|
|
|
|
|
|
|
|
|
|
-- redraw
|
|
|
|
|
if diag_cnt == 0 and _NG_VT_DIAG_NS ~= nil then
|
|
|
|
|
|
|
|
|
|
vim.api.nvim_buf_clear_namespace(bufnr, _NG_VT_DIAG_NS, 0, -1)
|
|
|
|
|
trace("no errors")
|
|
|
|
|
trace('no errors')
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
vim.api.nvim_buf_clear_namespace(bufnr, _NG_VT_DIAG_NS, 0, -1)
|
|
|
|
|
local errors = diagnostic.get(bufnr)
|
|
|
|
|
if #errors == 0 then
|
|
|
|
|
trace("no errors", errors)
|
|
|
|
|
trace('no errors', errors)
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
local uri = vim.uri_from_bufnr(bufnr)
|
|
|
|
|
local result = {diagnostics = errors, uri = errors[1].uri or uri}
|
|
|
|
|
local result = { diagnostics = errors, uri = errors[1].uri or uri }
|
|
|
|
|
|
|
|
|
|
trace(result)
|
|
|
|
|
local marker = update_err_marker_async()
|
|
|
|
|
marker(result, {bufnr = bufnr, method = 'textDocument/publishDiagnostics'})
|
|
|
|
|
marker(result, { bufnr = bufnr, method = 'textDocument/publishDiagnostics' })
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- TODO: update the marker
|
|
|
|
|
if _NgConfigValues.diagnostic_scrollbar_sign then
|
|
|
|
|
vim.notify("config deprecated, set lsp.diagnostic_scrollbar_sign instead", vim.lsp.log_levels.WARN)
|
|
|
|
|
vim.notify('config deprecated, set lsp.diagnostic_scrollbar_sign instead', vim.lsp.log_levels.WARN)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if _NgConfigValues.lsp.diagnostic_scrollbar_sign then
|
|
|
|
|
vim.cmd [[autocmd WinScrolled * lua require'navigator.diagnostics'.update_err_marker()]]
|
|
|
|
|
vim.cmd([[autocmd WinScrolled * lua require'navigator.diagnostics'.update_err_marker()]])
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function M.get_line_diagnostic()
|
|
|
|
|
local lnum = vim.api.nvim_win_get_cursor(0)[1] - 1
|
|
|
|
|
return diagnostic.get(vim.api.nvim_get_current_buf(), {lnum = lnum})
|
|
|
|
|
return diagnostic.get(vim.api.nvim_get_current_buf(), { lnum = lnum })
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function M.show_diagnostics(pos)
|
|
|
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
|
|
|
local lnum = vim.api.nvim_win_get_cursor(0)[1] - 1
|
|
|
|
|
local opt = {border = 'single'}
|
|
|
|
|
if diagnostic.open_float and type(diagnostic.open_float) == "function" then
|
|
|
|
|
local opt = { border = 'single' }
|
|
|
|
|
if diagnostic.open_float and type(diagnostic.open_float) == 'function' then
|
|
|
|
|
if pos == true then
|
|
|
|
|
opt.scope = "cursor"
|
|
|
|
|
opt.scope = 'cursor'
|
|
|
|
|
else
|
|
|
|
|
opt.scope = "line"
|
|
|
|
|
opt.scope = 'line'
|
|
|
|
|
end
|
|
|
|
|
diagnostic.open_float(bufnr, opt)
|
|
|
|
|
else
|
|
|
|
|