Skip to content

linrongbin16/lsp-progress.nvim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

f3df1df · Dec 16, 2024
Dec 16, 2024
Dec 16, 2024
Dec 16, 2024
Apr 2, 2024
May 17, 2024
Jan 11, 2024
May 17, 2024
Oct 11, 2023
Nov 7, 2023
Jul 15, 2024
Mar 7, 2023
Jul 15, 2024
Jan 31, 2023
Jul 4, 2024
Oct 11, 2023
Mar 11, 2024
Mar 11, 2024

Repository files navigation

lsp-progress.nvim

Neovim luarocks ci.yml codecov

A performant lsp progress status for Neovim.

default

Click here to see how to configure
require("lsp-progress").setup()

client-names

Click here to see how to configure
require("lsp-progress").setup({
  client_format = function(client_name, spinner, series_messages)
    if #series_messages == 0 then
      return nil
    end
    return {
      name = client_name,
      body = spinner .. " " .. table.concat(series_messages, ", "),
    }
  end,
  format = function(client_messages)
    --- @param name string
    --- @param msg string?
    --- @return string
    local function stringify(name, msg)
      return msg and string.format("%s %s", name, msg) or name
    end

    local sign = "" -- nf-fa-gear \uf013
    local lsp_clients = vim.lsp.get_active_clients()
    local messages_map = {}
    for _, climsg in ipairs(client_messages) do
      messages_map[climsg.name] = climsg.body
    end

    if #lsp_clients > 0 then
      table.sort(lsp_clients, function(a, b)
        return a.name < b.name
      end)
      local builder = {}
      for _, cli in ipairs(lsp_clients) do
        if
          type(cli) == "table"
          and type(cli.name) == "string"
          and string.len(cli.name) > 0
        then
          if messages_map[cli.name] then
            table.insert(builder, stringify(cli.name, messages_map[cli.name]))
          else
            table.insert(builder, stringify(cli.name))
          end
        end
      end
      if #builder > 0 then
        return sign .. " " .. table.concat(builder, ", ")
      end
    end
    return ""
  end,
})

green-check

Click here to see how to configure
require("lsp-progress").setup({
  decay = 1200,
  series_format = function(title, message, percentage, done)
    local builder = {}
    local has_title = false
    local has_message = false
    if type(title) == "string" and string.len(title) > 0 then
      table.insert(builder, title)
      has_title = true
    end
    if type(message) == "string" and string.len(message) > 0 then
      table.insert(builder, message)
      has_message = true
    end
    if percentage and (has_title or has_message) then
      table.insert(builder, string.format("(%.0f%%)", percentage))
    end
    return { msg = table.concat(builder, " "), done = done }
  end,
  client_format = function(client_name, spinner, series_messages)
    if #series_messages == 0 then
      return nil
    end
    local builder = {}
    local done = true
    for _, series in ipairs(series_messages) do
      if not series.done then
        done = false
      end
      table.insert(builder, series.msg)
    end
    if done then
      spinner = "" -- replace your check mark
    end
    return "["
      .. client_name
      .. "] "
      .. spinner
      .. " "
      .. table.concat(builder, ", ")
  end,
})

Table of contents

Performance

I use a 2-layer map to cache all lsp progress messages, thus split the O(N * M) time complexity calculation into almost O(1) on every LSP progress update.

N is active lsp clients count, M is token count of each lsp client.

For more details, please see Design & Technologies.

Requirement

Install

With packer.nvim
-- lua
return require('packer').startup(function(use)
  use {
    'linrongbin16/lsp-progress.nvim',
    config = function()
      require('lsp-progress').setup()
    end
  }
end)
With lazy.nvim
-- lua
require("lazy").setup({
  {
    'linrongbin16/lsp-progress.nvim',
    config = function()
      require('lsp-progress').setup()
    end
  }
})
With vim-plug
" vim
call plug#begin()

Plug 'linrongbin16/lsp-progress.nvim'

call plug#end()

lua require('lsp-progress').setup()

Usage

  • LspProgressStatusUpdated: user event to notify new status, and trigger statusline refresh.

  • require('lsp-progress').progress(opts): get lsp progress status, parameter opts is an optional lua table:

    require('lsp-progress').progress({
      format = ...,
      max_size = ...,
    })

    The fields are the same value passing to setup (see Configuration) for more dynamic abilities.

Integration

Important

Don't directly put require('lsp-progress').progress as lualine component or heirline's component provider, wrap it with a function to avoid the lazy dependency issue, see #131.

require("lualine").setup({
  sections = {
    -- Other Status Line components
    lualine_a = { ... },
    lualine_b = { ... },

    lualine_c = {
      function()
        -- invoke `progress` here.
        return require('lsp-progress').progress()
      end,
    },
    ...
  }
})

-- listen lsp-progress event and refresh lualine
vim.api.nvim_create_augroup("lualine_augroup", { clear = true })
vim.api.nvim_create_autocmd("User", {
  group = "lualine_augroup",
  pattern = "LspProgressStatusUpdated",
  callback = require("lualine").refresh,
})
local LspProgress = {
  provider = function()
    return require('lsp-progress').progress()
  end,
  update = {
    'User',
    pattern = 'LspProgressStatusUpdated',
    callback = vim.schedule_wrap(function()
      vim.cmd('redrawstatus')
    end),
  }
}

local StatusLine = {
  -- Other StatusLine components
  { ... },

  -- Lsp progress status component here
  LspProgress,
}

require('heirline').setup({
  statusline = StatusLine
})

Configuration

To configure options, please use:

require('lsp-progress').setup(opts)

The opts is an optional lua table that overwrite the default options.

For complete options and defaults, please check defaults.lua.

For more advanced configurations, please see Advanced Configuration.

Alternatives

  • lsp-status.nvim: Utility functions for getting diagnostic status and progress messages from LSP servers, for use in the Neovim statusline.
  • fidget.nvim: Standalone UI for nvim-lsp progress.

Contribute

Please open issue/PR for anything about lsp-progress.nvim.

Like lsp-progress.nvim? Consider

Github Sponsor Wechat Pay Alipay