Skip to content

Commit

Permalink
feat!: Switch to event-driven LSP progress polling by default
Browse files Browse the repository at this point in the history
Event-driven polling seems to be the "right" way to address #167;
see also neovim/neovim#26098.

Periodic polling is still supported, and useful for issues like #73, but
since Neovim's built-in ringbuf configuration is not designed for the
periodic use case, it doesn't make sense for this to be Fidget's default
behavior.
  • Loading branch information
j-hui committed Nov 20, 2023
1 parent 53f3297 commit 74b6196
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 16 deletions.
25 changes: 18 additions & 7 deletions doc/fidget.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ The following table shows the default options for this plugin:
{
-- Options related to LSP progress subsystem
progress = {
poll_rate = 5, -- How frequently to poll for progress messages
poll_rate = 0, -- How and when to poll for progress messages
suppress_on_insert = false, -- Suppress new messages while in insert mode
ignore_done_already = false, -- Ignore new tasks that are already complete
notification_group = -- How to get a progress message's notification group key
Expand Down Expand Up @@ -66,7 +66,7 @@ The following table shows the default options for this plugin:

-- Options related to notification subsystem
notification = {
poll_rate = 10, -- How frequently to poll and render notifications
poll_rate = 10, -- How frequently to update and render notifications
filter = vim.log.levels.INFO, -- Minimum notifications level
override_vim_notify = false, -- Automatically override vim.notify() with Fidget
configs = -- How to configure notification groups when instantiated
Expand Down Expand Up @@ -107,14 +107,25 @@ The following table shows the default options for this plugin:
```

progress.poll_rate
: How frequently to poll for progress messages
: How and when to poll for progress messages

Set to 0 to disable polling; you can still manually poll progress messages
by calling `fidget.progress.poll()`.
Set to `0` to immediately poll on each `LspProgress` event.

Measured in Hertz (frames per second).
Set to a positive number to poll for progress messages at the specified
frequency (Hz, i.e., polls per second). Combining a slow `poll_rate`
(e.g., `0.5`) with the `ignore_done_already` setting can be used to filter
out short-lived progress tasks, de-cluttering notifications.

Note that if too many LSP progress messages are sent between polls,
Neovim's progress ring buffer will overflow and messages will be
overwritten (dropped), possibly causing stale progress notifications.
Workarounds include using the `progress.lsp.progress_ringbuf_size` option,
or manually calling `fidget.notification.reset()` (see #167).

Set to `false` to disable polling altogether; you can still manually poll
progress messages by calling `fidget.progress.poll()`.

Type: `number` (default: `5`)
Type: `number | false` (default: `0`)

progress.suppress_on_insert
: Suppress new messages while in insert mode
Expand Down
2 changes: 1 addition & 1 deletion lua/fidget/notification.lua
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ M.default_config = {

--- Options related to notification subsystem
require("fidget.options").declare(M, "notification", {
--- How frequently to poll and render notifications
--- How frequently to update and render notifications
---
--- Measured in Hertz (frames per second).
---
Expand Down
31 changes: 23 additions & 8 deletions lua/fidget/progress.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,26 @@ local autocmd_id = nil

--- Options related to LSP progress notification subsystem
require("fidget.options").declare(M, "progress", {
--- How frequently to poll for progress messages
--- How and when to poll for progress messages
---
--- Set to 0 to disable polling; you can still manually poll progress messages
--- by calling `fidget.progress.poll()`.
--- Set to `0` to immediately poll on each `LspProgress` event.
---
--- Measured in Hertz (frames per second).
--- Set to a positive number to poll for progress messages at the specified
--- frequency (Hz, i.e., polls per second). Combining a slow `poll_rate`
--- (e.g., `0.5`) with the `ignore_done_already` setting can be used to filter
--- out short-lived progress tasks, de-cluttering notifications.
---
---@type number
poll_rate = 5,
--- Note that if too many LSP progress messages are sent between polls,
--- Neovim's progress ring buffer will overflow and messages will be
--- overwritten (dropped), possibly causing stale progress notifications.
--- Workarounds include using the `progress.lsp.progress_ringbuf_size` option,
--- or manually calling `fidget.notification.reset()` (see #167).
---
--- Set to `false` to disable polling altogether; you can still manually poll
--- progress messages by calling `fidget.progress.poll()`.
---
---@type number|false
poll_rate = 0,

--- Suppress new messages while in insert mode
---
Expand Down Expand Up @@ -75,9 +86,13 @@ require("fidget.options").declare(M, "progress", {
vim.api.nvim_del_autocmd(autocmd_id)
autocmd_id = nil
end
if M.options.poll_rate > 0 then
if M.options.poll_rate ~= false then
autocmd_id = M.lsp.on_progress_message(function()
M.poller:start_polling(M.options.poll_rate)
if M.options.poll_rate > 0 then
M.poller:start_polling(M.options.poll_rate)
else
M.poller:poll_once()
end
end)
end
end)
Expand Down

0 comments on commit 74b6196

Please sign in to comment.