- Save as
π.lua cd $(dirname path/to/π.lua)nvim π.lua:luafile %- Press
F5to π
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()" |