- Save as
π.lua
cd $(dirname path/to/π.lua)
nvim π.lua
:luafile %
- Press
F5
to π
The F5
bit is just for demonstration. In an actual statusline, you'll want to uncomment line 65 so it actually checks for LSP messages.
local config = { | |
delay_ms = 100, | |
frames = { | |
"#bcbcbc", | |
"#aaaaaa", | |
"#989898", | |
"#868686", | |
"#757575", | |
"#646464", | |
"#545454", | |
"#444444", | |
"#353535", | |
"#262626", | |
"#353535", | |
"#444444", | |
"#545454", | |
"#646464", | |
"#757575", | |
"#868686", | |
"#989898", | |
"#aaaaaa", | |
}, | |
} | |
-- HERE BE DRAGONS | |
local n_frames = #config.frames | |
-- Create highlight groups from frames | |
for i, fg in ipairs(config.frames) do | |
vim.api.nvim_set_hl(0, 'rainbow' .. i, { fg=fg, bg="none" }) | |
end | |
vim.api.nvim_set_hl(0, 'StatusLine', { fg="#bcbcbc", bg="none" }) | |
-- Global state. Gotta make that buffer-local or something | |
--- Frame index | |
local i = 1 | |
--- If this is true, the icon will start cycling through frames | |
local messages_available = false | |
--- Check for LSP messages | |
--@returns bool Are messages available for any client attached to this buffer? | |
local function has_messages(buf_id) | |
for _, client in pairs(vim.lsp.buf_get_clients(buf_id)) do | |
if not vim.tbl_isempty(client.messages.messages) then return true end | |
for _, progress in pairs(client.messages.progress) do | |
if not progress.done then return true end | |
end | |
end | |
return false | |
end | |
local t = vim.loop.new_timer() | |
vim.api.nvim_create_augroup("rainbow_icon", {}) | |
vim.api.nvim_create_autocmd("User", { | |
pattern = "LspProgressUpdate", | |
group = "rainbow_icon", | |
desc = "Update rainbow", | |
callback = function() | |
local buf_id = vim.api.nvim_get_current_buf() | |
if t:get_due_in() == 0 then | |
t:start(config.delay_ms, config.delay_ms, function() | |
-- This is just for demonstration. With a real LSP client, | |
-- you'll want to uncomment this line: | |
--messages_available = has_messages(buf_id) | |
if messages_available then | |
-- Cycle through colors | |
i = i % n_frames + 1 | |
t:again() | |
else | |
-- Reset cycle index for next run | |
i = 1 | |
t:stop() | |
end | |
-- Redraw statusline on next tick | |
vim.schedule(function() vim.api.nvim_command("redrawstatus") end) | |
end) | |
end | |
end, | |
}) | |
function statusline() | |
-- Icon | |
local icon = "[I'M AN ICON!]" | |
if messages_available then | |
return '%#rainbow' .. i .. '#' .. icon .. '%#StatusLine# <- π' | |
else | |
return '%#StatusLine#' .. icon .. ' Now press F5 to π' | |
end | |
end | |
vim.keymap.set('n', | |
'<f5>', | |
function() | |
messages_available = not messages_available | |
vim.cmd("doautocmd User LspProgressUpdate") | |
end, | |
{ buffer = true, desc = "Toggle rainbow" } | |
) | |
vim.o.statusline="%!v:lua.statusline()" |