Need help with lsp-status.nvim?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

nvim-lua
363 Stars 25 Forks MIT License 71 Commits 12 Opened issues

Description

Utility functions for getting diagnostic status and progress messages from LSP servers, for use in the Neovim statusline

Services available

!
?

Need anything else?

Contributors list

lsp-status.nvim

This is a Neovim plugin/library for generating statusline components from the built-in LSP client.

Notices

  • 2021/03/13: Some users report success using the Google "Noto Emoji" font for
    status_symbol
    and
    indicator_hint
    .
  • 2020/11/19: Please note that the default diagnostics symbols require Font Awesome or a Nerd Font. You may also change the diagnostics symbols as shown in the configuration section.
  • 2020/11/13: Due to this PR, you must update to the latest Neovim
    master
    to avoid errors with the old diagnostics API. See issue #19 for more information.
  • 2020/05/25: There has been a minor breaking change to the API:
    extension_callbacks
    is now named
    extensions
    . There have also been a number of additions and improvements; see the below (specifically Configuration and Example Use) for details.

Contents

  1. Examples
  2. Installation
  3. Usage
    1. Protocol Extensions
    2. Configuration
  4. Example Use
    1. All together, now
  5. Status
  6. Contributing

Examples

Show the current containing function (like

b:coc_current_function
): Statusline showing current function and no errors

Easily access diagnostic counts: Statusline showing some error indicators

Show progress messages from servers: Statusline showing progress messages from a server

Installation

You will need a version of Neovim that includes the built-in LSP client (right now, that means nightly). Use your preferred package/plugin manager. With

vim-packager
, this looks like:

vim
call packager#add('nvim-lua/lsp-status.nvim')

Usage

The plugin provides several utilities:

lua
update_current_function() -- Set/reset the b:lsp_current_function variable
-- Shows the current function, method, class, struct, interface, enum, module, or namespace
diagnostics() -- Return a table with all diagnostic counts for the current buffer
messages() -- Return a table listing progress and other status messages for display
register_progress() -- Register the provided handler for progress messages
register_client() -- Register a client for messages
-- Integrate misc. LS protocol extensions into the messages framework
-- Each extension table contains a set of handlers and a setup() function 
-- returning said handlers
extensions = { clangd, pyls_ms }
-- Set up a client for use with lsp-status. Calls register_client() and sets up 
-- buffer autocommands
on_attach(client) 
config(config_vals) -- Configure lsp-status
-- Table of client capabilities extended to signal support for progress messages
capabilities 
status() -- One example out-of-the-box statusline component (as shown in the images above)

Protocol Extensions

lsp-status.nvim
supports messaging-related protocol extensions offered by
clangd
and Microsoft's Python language server (
python/setStatusBarMessage
,
python/beginProgress
,
python/reportProgress
, and
python/endProgress
). To use these extensions, register the handlers provided in the
extensions
table (the keys for the handlers are the relevant LSP method name).

Note: For

clangd
, you must also set
init_options = { clangdFileStatus = true }
.

New: You can also call

lsp_status.extensions..setup()
to return the full set of handlers, as shown below.

Configuration

You can configure

lsp-status.nvim
using the
config
function, which takes a table of configuration values. The following configuration options are supported:
  • kind_labels
    : An optional map from LSP symbol kinds to label symbols. Used to decorate the current function name. Default:
    {}
  • select_symbol
    : An optional handler of the form
    function(cursor_pos, document_symbol)
    that should return
    true
    if
    document_symbol
    (a
    DocumentSymbol
    ) should be accepted as the symbol currently containing the cursor.

For example, the sumneko lua server sends

valueRange
(which is not specified in the protocol) to give the range for a function's start and end. To respect
valueRange
, you can use the following configuration: ```lua lspstatus.config { selectsymbol = function(cursorpos, symbol) if symbol.valueRange then local valuerange = { ["start"] = { character = 0, line = vim.fn.byte2line(symbol.valueRange[1]) }, ["end"] = { character = 0, line = vim.fn.byte2line(symbol.valueRange[2]) } }
  return require("lsp-status.util").in_range(cursor_pos, value_range)
end

end }

- `current_function`: Boolean, `true` if the current function should be updated and displayed in the
  default statusline component.
- `show_filename`: Boolean, `true` if the filename should be displayed in the progress text.
- `indicator_*`-group: strings to show as diagnostic warnings. If you don't have Nerd/Awesome Fonts you can replace defaults with ASCII chars like this:
-- Put this somewhere near lspstatus.registerprogress() lspstatus.config({ indicatorerrors = 'E', indicatorwarnings = 'W', indicatorinfo = 'i', indicatorhint = '?', indicatorok = 'Ok', }) ``
-
indicatorseparator
: a string which goes between each diagnostic group symbol and its count.
  Defaults to whitespace.
-
component
separator
: a string which goes between each "chunk" of the statusline component (i.e.
  different diagnostic groups, messages). Defaults to whitespace.
-
diagnostics
: Boolean,
true
by default. If
false`, the default statusline component does not display LSP diagnostics.

Example Use

Here is an example configuration (also using

nvim-lsp
) showing how

lsp-status
can be integrated into one's statusline and other LSP configuration.

In any Lua file you load: ```lua local lspstatus = require('lsp-status') -- completioncustomizelsplabel as used in completion-nvim -- Optional: customize the kind labels used in identifying the current function. -- g:completioncustomizelsplabel is a dict mapping from LSP symbol kind -- to the string you want to display as a label -- lspstatus.config { kindlabels = vim.g.completioncustomizelsplabel }

-- Register the progress handler lspstatus.registerprogress() ```

Before calling

setup
for each relevant LSP client:

lua
-- Set default client capabilities plus window/workDoneProgress
config.capabilities = vim.tbl_extend('keep', config.capabilities or {}, lsp_status.capabilities)

In an

on_attach
function for each relevant LSP client:

lua
-- Register client for messages and set up buffer autocommands to update 
-- the statusline and the current function.
-- NOTE: on_attach is called with the client object, which is the "client" parameter below
lsp_status.on_attach(client)

Specific client configuration (following

nvim-lsp
conventions):

lua
clangd = {
  handlers = lsp_status.extensions.clangd.setup()
},
pyls_ms = {
  handlers = lsp_status.extensions.pyls_ms.setup()
},

LSP statusline segment

An example statusline segment is provided in lua/lsp-status/statusline. You are encouraged to read the source and develop your own statusline segment, but if you'd like something reasonable out-of-the-box, you can call

lsp_status.status()
somewhere in your statusline definition (make sure you have
require
'd the
lsp-status
module too!)

All together, now

Here's a complete example:

lua << END
local lsp_status = require('lsp-status')
lsp_status.register_progress()

local lspconfig = require('lspconfig')

-- Some arbitrary servers lspconfig.clangd.setup({ handlers = lsp_status.extensions.clangd.setup(), init_options = { clangdFileStatus = true }, on_attach = lsp_status.on_attach, capabilities = lsp_status.capabilities })

lspconfig.pyls_ms.setup({ handlers = lsp_status.extensions.pyls_ms.setup(), settings = { python = { workspaceSymbols = { enabled = true }}}, on_attach = lsp_status.on_attach, capabilities = lsp_status.capabilities })

lspconfig.ghcide.setup({ on_attach = lsp_status.on_attach, capabilities = lsp_status.capabilities }) lspconfig.rust_analyzer.setup({ on_attach = lsp_status.on_attach, capabilities = lsp_status.capabilities }) END

" Statusline function! LspStatus() abort if luaeval('#vim.lsp.buf_get_clients() > 0') return luaeval("require('lsp-status').status()") endif

return '' endfunction

Status

This plugin is "complete" - it works in all the ways it was originally intended to, and it doesn't seem to break. That said, it hasn't been tested much, and I'm open to adding new features if others want them.

One thing that probably should be added is proper documentation of some sort. The code could also stand to be cleaned up.

Contributing

Bug reports and feature requests are welcome! PRs are doubly welcome!

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.