Skip to content

Instantly share code, notes, and snippets.

@runiq
Last active November 17, 2023 00:40
Show Gist options
  • Save runiq/2e81265c1c2a7587fbe9c184ceaa94c6 to your computer and use it in GitHub Desktop.
Save runiq/2e81265c1c2a7587fbe9c184ceaa94c6 to your computer and use it in GitHub Desktop.
🌈

HOW TO 🌈

  1. Save as 🌈.lua
  2. cd $(dirname path/to/🌈.lua)
  3. nvim 🌈.lua
  4. :luafile %
  5. 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()"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment