Skip to content

Commit 97b2e8b

Browse files
authored
feat(lsp_status): use vim.loop.hrtime on older nvim versions (#1391)
* feat(lsp_status): use vim.loop.hrtime when vim.uv.hrtime is not supported. There's no need to do custom approximations when vim.uv.hrtime is not available, because vim.loop.hrtime should work on older nvim versions (see neovim/neovim#22846). * fix(lsp_stauts): don't append space if empty progress symbol * fix(lsp_status): improve readibility with parantheses around LSP name formatting
1 parent b8b60c7 commit 97b2e8b

File tree

2 files changed

+29
-37
lines changed

2 files changed

+29
-37
lines changed

lua/lualine/components/lsp_status.lua

+10-26
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,6 @@ local default_options = {
1414
ignore_lsp = {},
1515
}
1616

17-
---Advances the spinner every 80ms (or just once if precise time measurement is not supported) and returns the new
18-
---spinner symbol.
19-
function M:__advance_spinner()
20-
if vim.uv then
21-
self.__spinner_index = math.floor(vim.uv.hrtime() / (1e6 * 80))
22-
else
23-
self.__spinner_index = (self.__spinner_index or 0) + 1
24-
end
25-
self.__spinner_index = self.__spinner_index % #self.symbols.spinner
26-
-- The spinner symbols table is 1-indexed.
27-
return self.symbols.spinner[self.__spinner_index + 1]
28-
end
29-
3017
function M:init(options)
3118
-- Run `super()`.
3219
M.super.init(self, options)
@@ -65,20 +52,18 @@ function M:init(options)
6552
end
6653

6754
function M:update_status()
68-
local bufnr = vim.api.nvim_get_current_buf()
6955
local result = {}
7056

71-
-- Retrieve the active LSPs in the current buffer in a backwards-compatible way.
72-
local clients
73-
if vim.lsp.get_clients then
74-
clients = vim.lsp.get_clients { bufnr = bufnr }
75-
else
76-
---@diagnostic disable-next-line: deprecated
77-
clients = vim.lsp.get_active_clients { bufnr = bufnr }
78-
end
57+
-- Backwards-compatible function to get the active LSP clients.
58+
---@diagnostic disable-next-line: deprecated
59+
local get_lsp_clients = vim.lsp.get_clients or vim.lsp.get_active_clients
60+
local clients = get_lsp_clients { bufnr = vim.api.nvim_get_current_buf() }
7961

80-
-- Advance the spinner only once, not for each client (otherwise the spinners will skip steps).
81-
local spinner_symbol = self:__advance_spinner()
62+
-- Backwards-compatible function to get the current time in nanoseconds.
63+
local hrtime = (vim.uv or vim.loop).hrtime
64+
-- Advance the spinner every 80ms only once, not for each client (otherwise the spinners will skip steps).
65+
-- NOTE: the spinner symbols table is 1-indexed.
66+
local spinner_symbol = self.symbols.spinner[math.floor(hrtime() / (1e6 * 80)) % #self.symbols.spinner + 1]
8267

8368
for _, client in ipairs(clients) do
8469
local status
@@ -91,10 +76,9 @@ function M:update_status()
9176

9277
-- Backwards-compatible function to check if a list contains a value.
9378
local list_contains = vim.list_contains or vim.tbl_contains
94-
9579
-- Append the status to the LSP only if it supports progress reporting and is not ignored.
9680
if not list_contains(self.options.ignore_lsp, client.name) then
97-
table.insert(result, client.name .. (status and ' ' .. status or ''))
81+
table.insert(result, client.name .. ((status and status ~= '') and (' ' .. status) or ''))
9882
end
9983
end
10084
return table.concat(result, self.symbols.separator)

tests/spec/component_spec.lua

+19-11
Original file line numberDiff line numberDiff line change
@@ -931,13 +931,17 @@ describe('lsp_status component', function()
931931
assert_comp_ins(lsp_status_comp, ' lua_ls')
932932
end)
933933

934-
it('shows LSP progress when supported with precise time measurement', function()
934+
it('shows LSP progress when supported', function()
935935
vim.cmd('edit ' .. file)
936936
stub(vim.lsp, 'get_clients')
937937
vim.lsp.get_clients.on_call_with({ bufnr = vim.api.nvim_get_current_buf() }).returns { { id = 2, name = 'lua_ls' } }
938-
vim.uv = vim.uv or {}
939-
stub(vim.uv, 'hrtime')
940-
vim.uv.hrtime.on_call_with().returns(12 * 1e6 * 80)
938+
if vim.uv and vim.uv.hrtime then
939+
stub(vim.uv, 'hrtime')
940+
vim.uv.hrtime.on_call_with().returns(12 * 1e6 * 80)
941+
elseif vim.loop and vim.loop.hrtime then
942+
stub(vim.loop, 'hrtime')
943+
vim.loop.hrtime.on_call_with().returns(12 * 1e6 * 80)
944+
end
941945

942946
local ok = pcall(vim.api.nvim_exec_autocmds, 'LspProgress', {
943947
data = { client_id = 2, params = { value = { kind = 'begin' } } },
@@ -950,24 +954,24 @@ describe('lsp_status component', function()
950954
end
951955
end)
952956

953-
it('shows LSP progress when supported without precise time measurement', function()
957+
it('shows LSP done when supported', function()
954958
vim.cmd('edit ' .. file)
955959
stub(vim.lsp, 'get_clients')
956960
vim.lsp.get_clients.on_call_with({ bufnr = vim.api.nvim_get_current_buf() }).returns { { id = 2, name = 'lua_ls' } }
957-
vim.uv = nil
958961

959962
local ok = pcall(vim.api.nvim_exec_autocmds, 'LspProgress', {
960963
data = { client_id = 2, params = { value = { kind = 'begin' } } },
964+
}) and pcall(vim.api.nvim_exec_autocmds, 'LspProgress', {
965+
data = { client_id = 2, params = { value = { kind = 'end' } } },
961966
})
962967

963968
-- Skip assertion if LSP progress updates are not supported by the current `nvim` version.
964969
if ok then
965-
-- We start from 0 and advanced by 1, so use spinner symbol 1.
966-
assert_comp_ins(lsp_status_comp, ' lua_ls ⠙')
970+
assert_comp_ins(lsp_status_comp, ' lua_ls ✓')
967971
end
968972
end)
969973

970-
it('shows LSP progress when supported with precise time measurement', function()
974+
it('shows LSP done when supported and no begin', function()
971975
vim.cmd('edit ' .. file)
972976
stub(vim.lsp, 'get_clients')
973977
vim.lsp.get_clients.on_call_with({ bufnr = vim.api.nvim_get_current_buf() }).returns { { id = 2, name = 'lua_ls' } }
@@ -982,7 +986,11 @@ describe('lsp_status component', function()
982986
end
983987
end)
984988

985-
it('shows LSP done when supported', function()
989+
it('does not add unnecessary space separator when LSP progress symbol is empty', function()
990+
local opts_no_done = opts
991+
opts_no_done.symbols = { done = '' }
992+
local lsp_status_comp_no_done = helpers.init_component('lsp_status', opts)
993+
986994
vim.cmd('edit ' .. file)
987995
stub(vim.lsp, 'get_clients')
988996
vim.lsp.get_clients.on_call_with({ bufnr = vim.api.nvim_get_current_buf() }).returns { { id = 2, name = 'lua_ls' } }
@@ -995,7 +1003,7 @@ describe('lsp_status component', function()
9951003

9961004
-- Skip assertion if LSP progress updates are not supported by the current `nvim` version.
9971005
if ok then
998-
assert_comp_ins(lsp_status_comp, ' lua_ls')
1006+
assert_comp_ins(lsp_status_comp_no_done, ' lua_ls')
9991007
end
10001008
end)
10011009
end)

0 commit comments

Comments
 (0)