From 88e73bf5aa2bdc7628c1cc8350dbc22d4fe19271 Mon Sep 17 00:00:00 2001 From: Toby She Date: Sun, 9 Mar 2025 23:05:12 -0400 Subject: [PATCH 1/3] added clangd file status integration --- README.md | 14 +++++ lua/fidget/integration.lua | 1 + lua/fidget/integration/clangd.lua | 87 +++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 lua/fidget/integration/clangd.lua diff --git a/README.md b/README.md index e3c17aa..5674887 100644 --- a/README.md +++ b/README.md @@ -245,6 +245,20 @@ Available options are shown below: ["xcodebuild-nvim"] = { enable = true, -- Integrate with wojciech-kulik/xcodebuild.nvim (if installed) }, + ["clangd"] = { + --- Integrate with clangd LSP (if running) + --- Show clangd parsing progress + --- Note: if enabled, vim.lsp.handlers["textDocument/clangd.fileStatus"] will be hooked + --- You can use the handler of this sub module directly + enable = false, + + --- Do not show notification if clangd isn't busy + --- for more than this number of ms + notification_delay = 500, + + --- Annotation string shown next to the message + annote = "clangd", + }, }, -- Options related to logging diff --git a/lua/fidget/integration.lua b/lua/fidget/integration.lua index d71be2e..f271d4b 100644 --- a/lua/fidget/integration.lua +++ b/lua/fidget/integration.lua @@ -3,6 +3,7 @@ local M = {} M.options = { ["nvim-tree"] = require("fidget.integration.nvim-tree"), ["xcodebuild-nvim"] = require("fidget.integration.xcodebuild-nvim"), + ["clangd"] = require("fidget.integration.clangd"), } require("fidget.options").declare(M, "integration", M.options) diff --git a/lua/fidget/integration/clangd.lua b/lua/fidget/integration/clangd.lua new file mode 100644 index 0000000..d2d7847 --- /dev/null +++ b/lua/fidget/integration/clangd.lua @@ -0,0 +1,87 @@ +local M = {} + +---@options integration.clangd [[ +--- clangd integration +M.options = { + --- Integrate with clangd LSP (if running) + --- Show clangd parsing progress + --- Note: if enabled, vim.lsp.handlers["textDocument/clangd.fileStatus"] will be hooked + --- You can use the handler of this sub module directly + ---@type boolean + enable = false, + + --- Do not show notification if clangd isn't busy + --- for more than this number of ms + ---@type integer + notification_delay = 500, + + --- Annotation string shown next to the message + ---@type string + annote = "clangd", +} + +local last_step = 0 -- 0: just created, 1: shown, 2: completed +local notify = require"fidget.notification".notify +local timer = nil +local function stop_timer() + if timer then + timer:stop() + timer:close() + timer = nil + end +end + +M.handler = function(err, result, ctx, config) + if not result.state then return end + stop_timer() + + local message = result.state + local opts = { + key = "clangd.fileStatus", + group = ctx.client_id, + annote = M.options.annote, + ttl = math.huge, + } + + if message == "idle" then + if last_step ~= 1 then + -- no notification displayed + last_step = 2 + return + end + -- update notification + last_step = 2 + message = "Completed" + opts.ttl = 0 + notify(message, vim.log.levels.INFO, opts) + return + end + + last_step = 0 + + if M.options.notification_delay == 0 then + last_step = 1 + notify(message, vim.log.levels.INFO, opts) + return + end + + timer = vim.uv.new_timer() + timer:start(M.options.notification_delay, 0, function() + stop_timer() + vim.schedule(function() + if last_step == 0 then + last_step = 1 + notify(message, vim.log.levels.INFO, opts) + end + end) + end) +end + +require("fidget.options").declare(M, "integration.clangd", M.options, function() + if not M.options.enable then + return + end + vim.lsp.handlers["textDocument/clangd.fileStatus"] = M.handler +end) + +return M From 6bdd87caa1c86e1a010048168533b158f8751c40 Mon Sep 17 00:00:00 2001 From: Toby She Date: Mon, 10 Mar 2025 10:59:48 -0400 Subject: [PATCH 2/3] update doc --- README.md | 9 ++++++++- doc/fidget.txt | 21 +++++++++++++++++++++ lua/fidget/integration/clangd.lua | 9 ++++++++- 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5674887..7688caf 100644 --- a/README.md +++ b/README.md @@ -246,8 +246,15 @@ Available options are shown below: enable = true, -- Integrate with wojciech-kulik/xcodebuild.nvim (if installed) }, ["clangd"] = { - --- Integrate with clangd LSP (if running) + --- Integrate with clangd LSP clangdFileStatus --- Show clangd parsing progress + --- init_options.clangdFileStatus = true must be set in clangd LSP config + --- Example using lspconfig: + --- lspconfig.clangd.setup { + --- init_options = { + --- clangdFileStatus = true + --- } + --- } --- Note: if enabled, vim.lsp.handlers["textDocument/clangd.fileStatus"] will be hooked --- You can use the handler of this sub module directly enable = false, diff --git a/doc/fidget.txt b/doc/fidget.txt index 512ca10..34adf97 100644 --- a/doc/fidget.txt +++ b/doc/fidget.txt @@ -199,6 +199,27 @@ Available options are shown below: ["xcodebuild-nvim"] = { enable = true, -- Integrate with wojciech-kulik/xcodebuild.nvim (if installed) }, + ["clangd"] = { + --- Integrate with clangd LSP clangdFileStatus + --- Show clangd parsing progress + --- init_options.clangdFileStatus = true must be set in clangd LSP config + --- Example using lspconfig: + --- lspconfig.clangd.setup { + --- init_options = { + --- clangdFileStatus = true + --- } + --- } + --- Note: if enabled, vim.lsp.handlers["textDocument/clangd.fileStatus"] will be hooked + --- You can use the handler of this sub module directly + enable = false, + + --- Do not show notification if clangd isn't busy + --- for more than this number of ms + notification_delay = 500, + + --- Annotation string shown next to the message + annote = "clangd", + }, }, -- Options related to logging diff --git a/lua/fidget/integration/clangd.lua b/lua/fidget/integration/clangd.lua index d2d7847..188ca5b 100644 --- a/lua/fidget/integration/clangd.lua +++ b/lua/fidget/integration/clangd.lua @@ -3,8 +3,15 @@ local M = {} ---@options integration.clangd [[ --- clangd integration M.options = { - --- Integrate with clangd LSP (if running) + --- Integrate with clangd LSP clangdFileStatus --- Show clangd parsing progress + --- init_options.clangdFileStatus = true must be set in clangd LSP config + --- Example using lspconfig: + --- lspconfig.clangd.setup { + --- init_options = { + --- clangdFileStatus = true + --- } + --- } --- Note: if enabled, vim.lsp.handlers["textDocument/clangd.fileStatus"] will be hooked --- You can use the handler of this sub module directly ---@type boolean From 0713e7c53ddebe6ce24ce78df85ac10476b48d6a Mon Sep 17 00:00:00 2001 From: Toby She Date: Thu, 10 Apr 2025 18:04:02 -0400 Subject: [PATCH 3/3] make clang integration more reliable when multiple files are opened --- lua/fidget/integration/clangd.lua | 70 ++++++++++++++++++------------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/lua/fidget/integration/clangd.lua b/lua/fidget/integration/clangd.lua index 188ca5b..85b7b77 100644 --- a/lua/fidget/integration/clangd.lua +++ b/lua/fidget/integration/clangd.lua @@ -27,68 +27,80 @@ M.options = { annote = "clangd", } -local last_step = 0 -- 0: just created, 1: shown, 2: completed local notify = require"fidget.notification".notify -local timer = nil -local function stop_timer() - if timer then - timer:stop() - timer:close() - timer = nil +local file_status = {} +local function stop_timer(status) + if status.timer then + status.timer:stop() + status.timer:close() + status.timer = nil end end M.handler = function(err, result, ctx, config) if not result.state then return end - stop_timer() - + local key = result.uri local message = result.state local opts = { - key = "clangd.fileStatus", - group = ctx.client_id, + key = key, + group = "clangd.fileStatus", annote = M.options.annote, ttl = math.huge, } + if not file_status[key] then + file_status[key] = { + message = message, + complete = false, + timer = nil, + busy = false, + } + end + local status = file_status[key] + status.message = message + if message == "idle" then - if last_step ~= 1 then + stop_timer(status) + status.complete = true + if not status.busy then -- no notification displayed - last_step = 2 + status.busy = false return end -- update notification - last_step = 2 + status.busy = false message = "Completed" opts.ttl = 0 notify(message, vim.log.levels.INFO, opts) return end - last_step = 0 - + status.complete = false if M.options.notification_delay == 0 then - last_step = 1 - notify(message, vim.log.levels.INFO, opts) - return + status.busy = true end - timer = vim.uv.new_timer() - timer:start(M.options.notification_delay, 0, function() - stop_timer() - vim.schedule(function() - if last_step == 0 then - last_step = 1 - notify(message, vim.log.levels.INFO, opts) - end + if status.busy then + notify(message, vim.log.levels.INFO, opts) + elseif not status.timer then + status.timer = vim.uv.new_timer() + status.timer:start(M.options.notification_delay, 0, function() + vim.schedule(function() + stop_timer(status) + if not status.complete then + status.busy = true + notify(status.message, vim.log.levels.INFO, opts) + end + end) end) - end) + end end require("fidget.options").declare(M, "integration.clangd", M.options, function() if not M.options.enable then return end - vim.lsp.handlers["textDocument/clangd.fileStatus"] = M.handler + vim.lsp.handlers["textDocument/clangd.fileStatus"] = M.handler end) return M