Created
October 6, 2022 22:09
-
-
Save mvllow/e423a9be50d43a784d99626222d21b75 to your computer and use it in GitHub Desktop.
Custom statusline/winbar
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local install_path = vim.fn.stdpath("data") .. "/site/pack/packer/start/packer.nvim" | |
if vim.fn.empty(vim.fn.glob(install_path)) > 0 then | |
vim.fn.execute("!git clone --depth 1 https://github.com/wbthomason/packer.nvim " .. install_path) | |
end | |
require("packer").startup(function(use) | |
use("wbthomason/packer.nvim") | |
use({ | |
"rose-pine/neovim", | |
as = "rose-pine", | |
config = function() | |
require("rose-pine").setup({ disable_italics = true }) | |
vim.cmd("colorscheme rose-pine") | |
end, | |
}) | |
use("editorconfig/editorconfig-vim") | |
use({ | |
"nvim-treesitter/nvim-treesitter", | |
run = ":TSUpdate", | |
config = function() | |
require("nvim-treesitter.configs").setup({ | |
ensure_installed = "all", | |
ignore_install = { "phpdoc" }, | |
highlight = { enable = true }, | |
}) | |
end, | |
}) | |
use({ | |
"numToStr/Comment.nvim", | |
requires = "JoosepAlviste/nvim-ts-context-commentstring", | |
config = function() | |
require("nvim-treesitter.configs").setup({ | |
context_commentstring = { | |
enable = true, | |
enable_autocmd = false, | |
}, | |
}) | |
require("Comment").setup({ | |
pre_hook = require("ts_context_commentstring.integrations.comment_nvim").create_pre_hook(), | |
}) | |
end, | |
}) | |
use({ | |
"nvim-telescope/telescope.nvim", | |
requires = "nvim-lua/plenary.nvim", | |
config = function() | |
require("telescope").setup({}) | |
end, | |
}) | |
use({ | |
"neovim/nvim-lspconfig", | |
requires = { | |
"folke/lua-dev.nvim", | |
"williamboman/mason.nvim", | |
"williamboman/mason-lspconfig.nvim", | |
"WhoIsSethDaniel/mason-tool-installer.nvim", | |
}, | |
config = function() | |
require("mason").setup() | |
require("mason-tool-installer").setup({}) | |
local function on_attach(_, bufnr) | |
local opts = { buffer = bufnr, silent = true } | |
vim.keymap.set("i", "<c-k>", vim.lsp.buf.signature_help, opts) | |
vim.keymap.set("n", "<leader>a", vim.lsp.buf.code_action, opts) | |
vim.keymap.set("n", "<leader>r", vim.lsp.buf.rename, opts) | |
vim.keymap.set("n", "K", vim.lsp.buf.hover, opts) | |
vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts) | |
vim.keymap.set("n", "gi", vim.lsp.buf.implementation, opts) | |
vim.keymap.set("n", "gr", vim.lsp.buf.references, opts) | |
end | |
local capabilities = vim.lsp.protocol.make_client_capabilities() | |
-- Improve compatibility with nvim-cmp completions | |
local has_cmp_nvim_lsp, cmp_nvim_lsp = pcall(require, "cmp_nvim_lsp") | |
if has_cmp_nvim_lsp then | |
capabilities = cmp_nvim_lsp.update_capabilities(capabilities) | |
end | |
-- Automatically setup servers installed via `:MasonInstall` | |
require("mason-lspconfig").setup_handlers({ | |
function(server_name) | |
if server_name == "sumneko_lua" then | |
require("lspconfig")[server_name].setup(require("lua-dev").setup({ | |
on_attach = on_attach, | |
capabilities = capabilities, | |
})) | |
else | |
require("lspconfig")[server_name].setup({ | |
on_attach = on_attach, | |
capabilities = capabilities, | |
}) | |
end | |
end, | |
}) | |
end, | |
}) | |
use({ | |
"jose-elias-alvarez/null-ls.nvim", | |
requires = "nvim-lua/plenary.nvim", | |
config = function() | |
local null_ls = require("null-ls") | |
local sources = { | |
null_ls.builtins.formatting.stylua, | |
} | |
null_ls.setup({ | |
sources = sources, | |
on_attach = function(client, bufnr) | |
if client.supports_method("textDocument/formatting") then | |
vim.api.nvim_create_autocmd("BufWritePre", { | |
buffer = bufnr, | |
callback = function() | |
vim.lsp.buf.format({ | |
bufnr = bufnr, | |
filter = function(lsp_client) | |
return lsp_client.name == "null-ls" | |
end, | |
}) | |
end, | |
}) | |
end | |
end, | |
}) | |
end, | |
}) | |
end) | |
-- Set diagnostic sign column symbols | |
local signs = { "Error", "Warn", "Hint", "Info" } | |
for _, type in pairs(signs) do | |
local hl = string.format("DiagnosticSign%s", type) | |
vim.fn.sign_define(hl, { text = "●", texthl = hl, numhl = hl }) | |
end | |
M = {} | |
--- Re-evaluate function each time the statusline is redrawn. | |
--- @param fn string | |
function M.watch_fn(fn) | |
-- TODO: This seems unnecessarily hacky. Without it, however, messages | |
-- will not be updated. | |
-- | |
-- `%{luaeval(...)}` re-evaluates each time the statusline is redrawn. | |
-- | |
-- Ideally this wouldn't require a string version of our function, as | |
-- that makes typos more likely to go unnoticed and cause issues. Also, | |
-- using default variables within the passed function such as "%f" or | |
-- "%#SomeHighlightGroup#" no longer work with this method. | |
return '%<%{luaeval("' .. fn .. '")}' | |
end | |
--- LSP loading status | |
function M.lsp_status() | |
local messages = vim.lsp.util.get_progress_messages() | |
local mode = vim.api.nvim_get_mode().mode | |
-- If neovim is not in normal mode, or if there are no messages. | |
if mode ~= "n" or vim.tbl_isempty(messages) then | |
return "" | |
end | |
local percentage | |
local result = {} | |
for _, msg in pairs(messages) do | |
if msg.message then | |
table.insert(result, msg.title .. ": " .. msg.message) | |
else | |
table.insert(result, msg.title) | |
end | |
if msg.percentage then | |
percentage = math.max(percentage or 0, msg.percentage) | |
end | |
end | |
if percentage then | |
return string.format("%03d: %s", percentage, table.concat(result, ", ")) | |
else | |
return table.concat(result, ", ") | |
end | |
end | |
--- Get first diagnostic message for the current line. | |
function M.diagnostic_message() | |
local severities = { "Error", "Warning" } | |
local diagnostics = vim.lsp.diagnostic.get_line_diagnostics() | |
if not next(diagnostics) then | |
return "" | |
end | |
if not severities[diagnostics[1].severity] then | |
return " " .. diagnostics[1].message .. " " | |
else | |
return " " .. severities[diagnostics[1].severity] .. ": " .. diagnostics[1].message .. " " | |
end | |
end | |
--- Get number of errors for the current buffer. | |
function M.diagnostic_error_status() | |
local num_errors = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.ERROR }) | |
if num_errors > 0 then | |
return "● " .. num_errors | |
end | |
return "" | |
end | |
--- Get number of warnings for the current buffer. | |
function M.diagnostic_warn_status() | |
local num_warnings = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.WARN }) | |
if num_warnings > 0 then | |
return "● " .. num_warnings | |
end | |
return "" | |
end | |
--- Configure statusline sections. | |
function M.statusline() | |
local lsp_error_count = "%#DiagnosticError#" .. M.watch_fn("M.diagnostic_error_status()") .. "%*" | |
local lsp_warning_count = "%#DiagnosticWarn#" .. M.watch_fn("M.diagnostic_warn_status()") .. "%*" | |
local sections = { | |
-- TODO: `%M` causes a layout shift between saved and unsaved buffer states | |
-- "%f %M", | |
"%f", | |
-- TODO: Highlight groups can cause mismatching backgrounds | |
-- against the statusline. | |
lsp_error_count, | |
lsp_warning_count, | |
M.watch_fn("M.lsp_status()"), | |
"%=", | |
"%l:%c", | |
} | |
--- Combine all sections with padding between each section. | |
--- TODO: Empty sections, e.g. when there are 0 errors, create an extra space. | |
return " " .. table.concat(sections, " ") .. " " | |
end | |
--- Configure winbar sections | |
function M.winbar() | |
local sections = { | |
"%=", | |
"%#PMenu#" .. M.watch_fn("M.diagnostic_message()") .. "%*", | |
} | |
--- Combine all sections with padding between each section | |
--- TODO: Empty sections, e.g. when there are 0 errors, create an extra space | |
return " " .. table.concat(sections, " ") .. " " | |
end | |
vim.diagnostic.config({ virtual_text = false }) | |
vim.opt.signcolumn = "yes" | |
vim.opt.statusline = M.statusline() | |
vim.opt.winbar = M.winbar() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment