Skip to content

Instantly share code, notes, and snippets.

@Lamarcke
Last active July 23, 2024 17:52
Show Gist options
  • Save Lamarcke/36e086dd3bb2cebc593d505e2f838e07 to your computer and use it in GitHub Desktop.
Save Lamarcke/36e086dd3bb2cebc593d505e2f838e07 to your computer and use it in GitHub Desktop.
Lualine config for LSP clients, formatters and linters
-- Returns a string with a list of attached LSP clients, including
-- formatters and linters from null-ls, nvim-lint and formatter.nvim
local function get_attached_clients()
local buf_clients = vim.lsp.get_active_clients({ bufnr = 0 })
if #buf_clients == 0 then
return "LSP Inactive"
end
local buf_ft = vim.bo.filetype
local buf_client_names = {}
-- add client
for _, client in pairs(buf_clients) do
if client.name ~= "copilot" and client.name ~= "null-ls" then
table.insert(buf_client_names, client.name)
end
end
-- Generally, you should use either null-ls or nvim-lint + formatter.nvim, not both.
-- Add sources (from null-ls)
-- null-ls registers each source as a separate attached client, so we need to filter for unique names down below.
local null_ls_s, null_ls = pcall(require, "null-ls")
if null_ls_s then
local sources = null_ls.get_sources()
for _, source in ipairs(sources) do
if source._validated then
for ft_name, ft_active in pairs(source.filetypes) do
if ft_name == buf_ft and ft_active then
table.insert(buf_client_names, source.name)
end
end
end
end
end
-- Add linters (from nvim-lint)
local lint_s, lint = pcall(require, "lint")
if lint_s then
for ft_k, ft_v in pairs(lint.linters_by_ft) do
if type(ft_v) == "table" then
for _, linter in ipairs(ft_v) do
if buf_ft == ft_k then
table.insert(buf_client_names, linter)
end
end
elseif type(ft_v) == "string" then
if buf_ft == ft_k then
table.insert(buf_client_names, ft_v)
end
end
end
end
-- Add formatters (from formatter.nvim)
local formatter_s, _ = pcall(require, "formatter")
if formatter_s then
local formatter_util = require("formatter.util")
for _, formatter in ipairs(formatter_util.get_available_formatters_for_ft(buf_ft)) do
if formatter then
table.insert(buf_client_names, formatter)
end
end
end
-- This needs to be a string only table so we can use concat below
local unique_client_names = {}
for _, client_name_target in ipairs(buf_client_names) do
local is_duplicate = false
for _, client_name_compare in ipairs(unique_client_names) do
if client_name_target == client_name_compare then
is_duplicate = true
end
end
if not is_duplicate then
table.insert(unique_client_names, client_name_target)
end
end
local client_names_str = table.concat(unique_client_names, ", ")
local language_servers = string.format("[%s]", client_names_str)
return language_servers
end
return {
"nvim-lualine/lualine.nvim",
event = { "VimEnter", "BufReadPost", "BufNewFile" },
config = function()
local attached_clients = {
get_attached_clients,
color = {
gui = "bold"
}
}
-- Example lualine setup
require("lualine").setup({
options = {
theme = "auto",
globalstatus = true,
component_separators = { left = "|", right = "|" },
},
sections = {
lualine_b = { "branch", "diff" },
lualine_x = { "diagnostics", attached_clients, "filetype" },
}
})
end,
}
@macielportugal
Copy link

Valeu mano

@xidiot
Copy link

xidiot commented Jun 21, 2024

Thank you!

@nicopoulos
Copy link

nicopoulos commented Jul 23, 2024

Very nice! I adapted the script for my use with conform.nvim instead of format.nvim and made some other minor changes.

local function get_attached_clients()
	-- Get active clients for current buffer
	local buf_clients = vim.lsp.get_clients({ bufnr = 0 })
	if #buf_clients == 0 then
		return "No client active"
	end
	local buf_ft = vim.bo.filetype
	local buf_client_names = {}
	local num_client_names = #buf_client_names

	-- Add lsp-clients active in the current buffer
	for _, client in pairs(buf_clients) do
		num_client_names = num_client_names + 1
		buf_client_names[num_client_names] = client.name
	end

	-- Add linters for the current filetype (nvim-lint)
	local lint_success, lint = pcall(require, "lint")
	if lint_success then
		for ft, ft_linters in pairs(lint.linters_by_ft) do
			if ft == buf_ft then
				if type(ft_linters) == "table" then
					for _, linter in pairs(ft_linters) do
						num_client_names = num_client_names + 1
						buf_client_names[num_client_names] = linter
					end
				else
					num_client_names = num_client_names + 1
					buf_client_names[num_client_names] = ft_linters
				end
			end
		end
	end

	-- Add formatters (conform.nvim)
	local conform_success, conform = pcall(require, "conform")
	if conform_success then
		for _, formatter in pairs(conform.list_formatters_for_buffer(0)) do
			if formatter then
				num_client_names = num_client_names + 1
				buf_client_names[num_client_names] = formatter
			end
		end
	end

	local client_names_str = table.concat(buf_client_names, ", ")
	local language_servers = string.format("[%s]", client_names_str)

	return language_servers
end

return {
	"nvim-lualine/lualine.nvim",
	dependencies = { "nvim-tree/nvim-web-devicons", "mfussenegger/nvim-lint", "stevearc/conform.nvim" },
	config = function()
		local attached_clients = {
			get_attached_clients,
			color = {
				gui = "bold",
			},
		}
		require("lualine").setup({
			options = {
				globalstatus = false,
			},
			sections = {
				lualine_x = {
					attached_clients,
				},
				--[[Some other sections here...]]
			},
		})
	end,
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment