Skip to content

Commit

Permalink
feat(ex.lsp.null_ls): add a new component to show actual null-ls sources
Browse files Browse the repository at this point in the history
.

.
  • Loading branch information
vladimir-popov committed Dec 28, 2023
1 parent 8f1ed1f commit 49e3982
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 0 deletions.
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ for `lualine.nvim` with additional components.
- [ex.git.branch](#exgitbranch)
- [ex.lsp.single](#exlspsingle)
- [ex.lsp.all](#exlspall)
- [ex.lsp.null_ls](#exlspnull_ls)
- [🛠️ Tools](#tools)

## 📥 <a name="installation">Installation</a>
Expand Down Expand Up @@ -471,6 +472,46 @@ on_click = function(clicks, button, modified)
end
```

### ex.lsp.null_ls

This component shows names of the
[null-ls](https://github.com/nvimtools/none-ls.nvim) sources according to the specified
[`query`](https://github.com/nvimtools/none-ls.nvim/blob/main/doc/SOURCES.md#get_sourcequery).
By default, it shows names of all sources actual to the current buffer. All
duplicated names are merged.

```lua
sections = {
lualine_a = {
{
'ex.lsp.null_ls',

-- The table or function that returns the table with the source query.
-- By default it shows only actual sorces. To show all registered sources
-- you can use just empty table:
-- query = {}
query = function()
return { filetype = vim.bo.filetype }
end,

-- The string separator between names
source_names_separator = ',',

-- The color for the disabled component:
disabled_color = { fg = 'grey' }

-- The color for the icon of the disabled component:
disabled_icon_color = { fg = 'grey' }
}
}
}
```

No one source:&nbsp;<img height="18" alt="null-ls-disabled" src="https://github.com/dokwork/lualine-ex/assets/6939832/04ce4a14-a3f9-4d90-a229-d19b78fa7c11">
The `jq` and the `spell` sources are active for the current buffer:<img height="18" alt="nulll-ls-enabled" src="https://github.com/dokwork/lualine-ex/assets/6939832/dda7dbb4-8647-49a2-8c28-8d29a617c2b9">



## 🛠️ <a name="tools">Tools</a>
This plugin provide additional tools to help you create your own components. Read more details here:
[Tools.md](Tools.md).
76 changes: 76 additions & 0 deletions lua/lualine/components/ex/lsp/null_ls.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
local log = require('plenary.log').new({ plugin = 'ex.lsp.null-ls' })

-- we should be ready to three possible cases:
-- * when null-ls is not loaded we should load it only on demand;
-- * when null-ls is not installed we should mock it to avoid errors;
-- * when it is installed and loaded we should it use it.
local null_ls = setmetatable({}, {
__index = function(self, key)
-- attempt to lazy load null-ls plugin
if rawget(self, 'is_installed') == nil then
local is_installed, null_ls = pcall(require, 'null-ls')
rawset(self, 'is_installed', is_installed)
rawset(self, 'null_ls', null_ls)
if is_installed then
log.debug('null-ls is installed')
else
log.warn('null-ls is not installed.')
end
end
-- return original plugin if it's installed
if rawget(self, 'is_installed') then
return rawget(self, 'null_ls')[key]
end
-- return mock:
if key == 'get_source' then
return {}
elseif key == 'is_registered' then
return false
else
return nil
end
end,
})

local NullLS = require('lualine.ex.component'):extend({
icon = '',
query = function()
return { filetype = vim.bo.filetype }
end,
component_name = 'ex_lsp_null_ls',
source_names_separator = ',',
is_enabled = function(component)
return null_ls.is_registered(component:get_query())
end,
})

function NullLS:get_query()
if type(self.options.query) == 'function' then
return self.options.query()
else
return self.options.query
end
end

-- get sources by query, and concatenate their unique names with {source_names_separator}
function NullLS:update_status()
local sources = null_ls.get_source(self:get_query())
log.fmt_debug(
'For query %s was found sources: %s',
vim.inspect(self.options.query),
vim.inspect(sources)
)
local names_set = {}
local names = {}
for _, source in pairs(sources) do
-- merge similar sources and escape special symbols
if not names_set[source.name] then
names_set[source.name] = true
local escaped_name = string.gsub(source.name, '%%', '%%%%')
table.insert(names, escaped_name)
end
end
return table.concat(names, self.options.source_names_separator)
end

return NullLS
47 changes: 47 additions & 0 deletions tests/components/null_ls_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
local null_ls = require('null-ls')
local l = require('tests.ex.lualine')
local t = require('tests.ex.busted') --:ignore_all_tests()

local eq = assert.are.equal

local component_name = 'ex.lsp.null_ls'
describe(component_name, function()
null_ls.setup({
sources = {
null_ls.builtins.completion.spell,
null_ls.builtins.formatting.stylua,
null_ls.builtins.hover.dictionary,
null_ls.builtins.diagnostics.clang_check,
},
})
describe('draw method', function()
it('should show the name of any source only once', function()
l.test_matched_component(component_name, function(ctbl)
local expected = {
clang_check = true,
spell = true,
dictionary = true,
stylua = true,
}
for name in string.gmatch(ctbl.value, '%w+') do
assert(expected[name], 'Unexpected name ' .. name)
expected[name] = nil
end
end)
end)
it('by default should return only sources for the current filetypes or for all', function()
vim.bo.filetype = 'lua'
l.test_matched_component(component_name, opts, function(ctbl)
for name in string.gmatch(ctbl.value, '%w+') do
assert(name ~= 'clang_check', 'Unexpected name ' .. name)
end
end)
end)
it('should show names only of sources sutisfied to the query', function()
local opts = { query = { method = null_ls.methods.HOVER } }
l.test_matched_component(component_name, opts, function(ctbl)
eq('dictionary', ctbl.value)
end)
end)
end)
end)

0 comments on commit 49e3982

Please sign in to comment.