diff --git a/lua/diagnostic.lua b/lua/diagnostic.lua index baa6148..84b6a06 100644 --- a/lua/diagnostic.lua +++ b/lua/diagnostic.lua @@ -3,9 +3,9 @@ local util = require 'diagnostic.util' local M = {} -- TODO change this to use vim.lsp.util.diagnostics_by_buf -M.bufferDiagnostic = {} local diagnosticTable = {} + local remove_diagnostics = function(diagnostics) -- Remove Index local remove = {} @@ -38,7 +38,7 @@ function M.modifyCallback() if not result then return end - local uri = result.uri + uri = result.uri local bufnr = vim.uri_to_bufnr(uri) if not bufnr then vim.lsp.err_message("LSP.publishDiagnostics: Couldn't find buffer for ", uri) @@ -48,7 +48,7 @@ function M.modifyCallback() if vim.api.nvim_get_var('diagnostic_level') ~= nil then result.diagnostics = remove_diagnostics(result.diagnostics) end - M.bufferDiagnostic[bufnr] = result + vim.lsp.util.buf_diagnostics_save_positions(bufnr, result.diagnostics) if vim.api.nvim_get_var('diagnostic_insert_delay') == 1 then if vim.api.nvim_get_mode()['mode'] == "i" or vim.api.nvim_get_mode()['mode'] == "ic" then return @@ -60,33 +60,31 @@ function M.modifyCallback() end function M.diagnostics_loclist(local_result) - if local_result and local_result.diagnostics then - for _, v in ipairs(local_result.diagnostics) do - v.uri = v.uri or local_result.uri + if local_result then + for _, v in ipairs(local_result) do + v.uri = v.uri or uri end end - vim.lsp.util.set_loclist(vim.lsp.util.locations_to_items(local_result.diagnostics)) + vim.lsp.util.set_loclist(util.locations_to_items(local_result)) end function M.publish_diagnostics(bufnr) if vim.fn.getcmdwintype() == ':' then return end + vim.lsp.util.buf_clear_diagnostics(bufnr) if #vim.lsp.buf_get_clients() == 0 then return end - local result = M.bufferDiagnostic[bufnr] - if result == nil then return end + local diagnostics = vim.lsp.util.diagnostics_by_buf[bufnr] + if diagnostics == nil then return end vim.fn.setloclist(0, {}, 'r') - vim.lsp.util.buf_clear_diagnostics(bufnr) - vim.lsp.util.buf_diagnostics_save_positions(bufnr, result.diagnostics) - util.buf_diagnostics_save_positions(bufnr, result.diagnostics) if vim.api.nvim_get_var('diagnostic_enable_underline') == 1 then - vim.lsp.util.buf_diagnostics_underline(bufnr, result.diagnostics) + vim.lsp.util.buf_diagnostics_underline(bufnr, diagnostics) end if vim.api.nvim_get_var('diagnostic_show_sign') == 1 then - util.buf_diagnostics_signs(bufnr, result.diagnostics) + util.buf_diagnostics_signs(bufnr, diagnostics) end if vim.api.nvim_get_var('diagnostic_enable_virtual_text') == 1 then - util.buf_diagnostics_virtual_text(bufnr, result.diagnostics) + util.buf_diagnostics_virtual_text(bufnr, diagnostics) end - M.diagnostics_loclist(result) + M.diagnostics_loclist(diagnostics) M.trigger_diagnostics_changed() end diff --git a/lua/diagnostic/util.lua b/lua/diagnostic/util.lua index 977efdc..41f2f12 100644 --- a/lua/diagnostic/util.lua +++ b/lua/diagnostic/util.lua @@ -102,6 +102,67 @@ function M.buf_diagnostics_virtual_text(bufnr, diagnostics) end end +local function sort_by_key(fn) + return function(a,b) + local ka, kb = fn(a), fn(b) + assert(#ka == #kb) + for i = 1, #ka do + if ka[i] ~= kb[i] then + return ka[i] < kb[i] + end + end + -- every value must have been equal here, which means it's not less than. + return false + end +end + +local position_sort = sort_by_key(function(v) + return {v.start.line, v.start.character} +end) + + +function M.locations_to_items(locations) + local items = {} + local grouped = setmetatable({}, { + __index = function(t, k) + local v = {} + rawset(t, k, v) + return v + end; + }) + local fname = api.nvim_buf_get_name(0) + for _, d in ipairs(locations) do + local range = d.range or d.targetSelectionRange + table.insert(grouped[fname], {start = range.start}) + end + + + local keys = vim.tbl_keys(grouped) + table.sort(keys) + local rows = grouped[fname] + + table.sort(rows, position_sort) + local bufnr = vim.fn.bufnr() + for _, temp in ipairs(rows) do + local pos = temp.start + local row = pos.line + local line = api.nvim_buf_get_lines(0, row, row+1, true)[1] + local col + if pos.character > #line then + col = #line + else + col = vim.str_byteindex(line, pos.character) + end + table.insert(items, { + bufnr = bufnr, + lnum = row + 1, + col = col + 1; + text = line + }) + end + return items +end + function M.buf_diagnostics_signs(bufnr, diagnostics) for _, diagnostic in ipairs(diagnostics) do local diagnostic_severity_map = {