From 6eeeb16ed49cac766280aa5388ffcd1982d9d062 Mon Sep 17 00:00:00 2001 From: Hubert Pelczarski <41551030+hoob3rt@users.noreply.github.com> Date: Mon, 22 Feb 2021 01:59:35 +0100 Subject: [PATCH] feat: diagnostics support (#95) --- README.md | 37 ++++--- lua/lualine/components/diagnostics.lua | 133 +++++++++++++++++++++++++ 2 files changed, 157 insertions(+), 13 deletions(-) create mode 100644 lua/lualine/components/diagnostics.lua diff --git a/README.md b/README.md index 5fadb07..f4364e1 100644 --- a/README.md +++ b/README.md @@ -132,16 +132,17 @@ lualine.inactive_sections = { Available components * general - * branch - * encoding - * fileformat + * branch (git branch) + * diagnostics (diagnostics count from your prefered source) + * encoding (file encoding) + * fileformat (file format) * filename * filetype - * location - * mode - * progress + * location (location in file in line:column format) + * mode (vim mode) + * progress (%progress in file) * plugin - * signify + * signify (signify status) @@ -219,6 +220,16 @@ color | nil | Sets custom color for the component in this format

`color In addition, some components have unique options. +* `diagnostics` component options + +Option | Default | Behaviour | Format +:------: | :------: | :----: | :---: +sources | `nil` | displays diagnostic count from defined source | array containing one or many string from set `{'nvim_lsp', 'coc', 'ale'}` +sections | `{'error', 'warn', 'info'}` | displays diagnostics of defined severity | array containing one or many string from set `{'error', 'warn', 'info'}` +color_error | `DiffDelete` foreground color | changes diagnostic's error section foreground color | color in `#rrggbb` format +color_warn | `DiffText` foreground color | changes diagnostic's warn section foreground color | color in `#rrggbb` format +color_info | `Normal` foreground color | changes diagnostic's info section foreground color | color in `#rrggbb` format + * `filename` component options Option | Default | Behaviour @@ -229,12 +240,12 @@ shorten | true | if `full_path` is true and `shorten` is `false` it shortens abs * `signify` component options -Option | Default | Behaviour -:------: | :------: | :----: -colored | true | displays signify status in color if set to `true` -color_added | `diffAdd` foreground color | changes signify's added section foreground color -color_modified | `diffChange` foreground color | changes signify's changed section foreground color -color_removed | `diffDelete` foreground color | changes signify's removed section foreground color +Option | Default | Behaviour | Format +:------: | :------: | :----: | :---: +colored | true | displays signify status in color if set to `true` | +color_added | `DiffAdd` foreground color | changes signify's added section foreground color | color in `#rrggbb` format +color_modified | `DiffChange` foreground color | changes signify's changed section foreground color | color in `#rrggbb` format +color_removed | `DiffDelete` foreground color | changes signify's removed section foreground color | color in `#rrggbb` format ##### Component options example diff --git a/lua/lualine/components/diagnostics.lua b/lua/lualine/components/diagnostics.lua new file mode 100644 index 0000000..d7f30d2 --- /dev/null +++ b/lua/lualine/components/diagnostics.lua @@ -0,0 +1,133 @@ +-- Copyright (c) 2020-2021 hoob3rt +-- MIT license, see LICENSE for more details. +local highlight = require('lualine.highlight') +local utils = require('lualine.utils.utils') + +local default_color_error = '#e32636' +local default_color_warn = '#ffdf00' +local default_color_info = '#ffffff' + +local diagnostic_sources = { + nvim_lsp = function() + local error_count = vim.lsp.diagnostic.get_count(0, 'Error') + local warning_count = vim.lsp.diagnostic.get_count(0, 'Warning') + local info_count = vim.lsp.diagnostic.get_count(0, 'Information') + + vim.lsp.diagnostic.get_count(0, 'Hint') + return error_count, warning_count, info_count + end, + coc = function() + local data = vim.b.coc_diagnostic_info + if data then + return data.error, data.warning, data.information + else + return 0, 0, 0 + end + end, + ale = function() + local ok, data = pcall(vim.fn['ale#statusline#Count'], vim.fn.bufnr()) + if ok then + return data.error, data.warning, data.info + else + return 0, 0, 0 + end + end, +} + +local function get_diagnostics(sources) + local result = {} + for index, source in ipairs(sources) do + local error_count, warning_count, info_count = diagnostic_sources[source]() + result[index] = {error = error_count, warn = warning_count, info = info_count} + end + return result +end + +local function diagnostics(options) + local symbols + if options.icons_enabled then + symbols = { + error = ' ', -- xf659 + warn = ' ', -- xf529 + info = ' ', -- xf7fc + } + else + symbols = { + error = 'E:', + warn = 'W:', + info = 'I:' + } + end + if options.sources == nil then + print('no sources for diagnostics configured') + return '' + end + if options.sections == nil then options.sections = {'error', 'warn', 'info'} end + if options.colored == nil then options.colored = true end + -- apply colors + if not options.color_error then + options.color_error = utils.extract_highlight_colors('DiffDelete', 'foreground') or default_color_error + end + if not options.color_warn then + options.color_warn = utils.extract_highlight_colors('DiffText', 'foreground') or default_color_warn + end + if not options.color_info then + options.color_info = utils.extract_highlight_colors('Normal', 'foreground') or default_color_info + end + + local highlight_groups = {} + local function add_highlights() + highlight_groups = { + error = highlight.create_component_highlight_group({ fg = options.color_error }, 'diagnostics_error', options), + warn = highlight.create_component_highlight_group({ fg = options.color_warn }, 'diagnostics_warn', options), + info = highlight.create_component_highlight_group({ fg = options.color_info }, 'diagnostics_info', options), + } + end + + if options.colored then + add_highlights() + utils.expand_set_theme(add_highlights) + end + + return function() + local error_count, warning_count, info_count = 0,0,0 + local diagnostic_data = get_diagnostics(options.sources) + for _, data in pairs(diagnostic_data) do + error_count = error_count + data.error + warning_count = warning_count + data.warn + info_count = info_count + data.info + end + local result = {} + local data = { + error = error_count, + warn = warning_count, + info = info_count, + } + if options.colored then + local colors = {} + for name, hl in pairs(highlight_groups) do + colors[name] = highlight.component_format_highlight(hl) + end + for _, section in ipairs(options.sections) do + if data[section] ~= nil and data[section] > 0 then + table.insert(result, colors[section]..symbols[section]..data[section]) + end + end + else + for _, section in ipairs(options.sections) do + if data[section] ~= nil and data[section] > 0 then + table.insert(result,symbols[section]..data[section]) + end + end + end + if result[1] ~= nil then + return table.concat(result, ' ') + else + return '' + end + end +end + +return { + init = function(options) return diagnostics(options) end, + get_diagnostics = get_diagnostics, +}