How do I display the current LSP server progress messages in the Neovim statusline?
Answer
vim.lsp.status()
Explanation
vim.lsp.status() returns the most recent LSP progress message as a plain string — things like "Loading workspace..." or "Indexing: 42%" sent by servers via the $/progress JSON-RPC notification. Including it in a custom statusline gives you real-time feedback on what the language server is doing, without needing fidget.nvim or any other plugin.
How it works
- Returns an empty string
''when no progress is active, so it disappears cleanly from the statusline when the server is idle - Neovim updates the internal progress state asynchronously as progress messages arrive
- The function itself is synchronous — it just reads the cached last message, so it is safe to call inside a statusline expression
Example
-- Use via the Vimscript bridge in a string statusline:
vim.o.statusline = '%f %=%{v:lua.vim.lsp.status()} %l:%c'
-- Or inside a Lua statusline builder:
local function lsp_progress()
local msg = vim.lsp.status()
return msg ~= '' and (' ' .. msg) or ''
end
-- Trigger a redraw when progress changes so the statusline stays current:
vim.api.nvim_create_autocmd('User', {
pattern = 'LspProgressUpdate',
callback = function() vim.cmd.redrawstatus() end,
})
Tips
- Without the
LspProgressUpdateautocmd the statusline only refreshes on cursor movement — adding the autocmd makes progress messages appear and disappear promptly vim.lsp.status()aggregates progress from all attached clients; if you need per-client messages, iterate overvim.lsp.get_clients({ bufnr = 0 })and read their progress tablesfidget.nvimprovides a richer floating notification UI if you want animated spinners and history, butvim.lsp.status()covers the common case with zero dependencies