From 9a9340960609a25762379113f6634c317decffc6 Mon Sep 17 00:00:00 2001
From: NotAShelf <raf@notashelf.dev>
Date: Sun, 19 Jan 2025 20:26:52 +0300
Subject: [PATCH] lsp/lightbulb: cleanup; modularize autocommand behaviour

---
 docs/release-notes/rl-0.8.md                | 16 +++++++++---
 modules/plugins/lsp/lightbulb/config.nix    | 27 +++++++++++++++++----
 modules/plugins/lsp/lightbulb/lightbulb.nix | 22 +++++++++++++++--
 3 files changed, 54 insertions(+), 11 deletions(-)

diff --git a/docs/release-notes/rl-0.8.md b/docs/release-notes/rl-0.8.md
index b06a071f..f5e9d0a0 100644
--- a/docs/release-notes/rl-0.8.md
+++ b/docs/release-notes/rl-0.8.md
@@ -31,6 +31,12 @@
   your Editorconfig configuration, or use an autocommand to set indentation
   values for buffers with the Nix filetype.
 
+- Add [](#opt-vim.lsp.lightbulb.autocmd.enable) for manually managing the
+  previously managed lightbulb autocommand.
+  - A warning will occur if [](#opt-vim.lsp.lightbulb.autocmd.enable) and
+    `vim.lsp.lightbulb.setupOpts.autocmd.enabled` are both set at the same time.
+    Pick only one.
+
 [amadaluzia](https://github.com/amadaluzia):
 
 [haskell-tools.nvim]: https://github.com/MrcJkb/haskell-tools.nvim
@@ -59,7 +65,8 @@
 - Add `vim.snippets.luasnip.setupOpts`, which was previously missing.
 - Add `"prettierd"` as a formatter option in
   `vim.languages.markdown.format.type`.
-- Add the following plugins from [mini.nvim](https://github.com/echasnovski/mini.nvim)
+- Add the following plugins from
+  [mini.nvim](https://github.com/echasnovski/mini.nvim)
   - `mini.ai`
   - `mini.align`
   - `mini.animate`
@@ -102,7 +109,8 @@
   - `mini.trailspace`
   - `mini.visits`
 - Add [fzf-lua](https://github.com/ibhagwan/fzf-lua) in `vim.fzf-lua`
-- Add [rainbow-delimiters](https://github.com/HiPhish/rainbow-delimiters.nvim) in `vim.visuals.rainbow-delimiters`
+- Add [rainbow-delimiters](https://github.com/HiPhish/rainbow-delimiters.nvim)
+  in `vim.visuals.rainbow-delimiters`
 - Add options to define highlights under [](#opt-vim.highlight)
 
 [kaktu5](https://github.com/kaktu5):
@@ -125,5 +133,5 @@
 
 [ARCIII](https://github.com/ArmandoCIII):
 
-- Add `vim.languages.zig.dap` support through pkgs.lldb dap adapter.
-  Code Inspiration from `vim.languages.clang.dap` implementation.
+- Add `vim.languages.zig.dap` support through pkgs.lldb dap adapter. Code
+  Inspiration from `vim.languages.clang.dap` implementation.
diff --git a/modules/plugins/lsp/lightbulb/config.nix b/modules/plugins/lsp/lightbulb/config.nix
index f17b8ad9..17e740ad 100644
--- a/modules/plugins/lsp/lightbulb/config.nix
+++ b/modules/plugins/lsp/lightbulb/config.nix
@@ -4,6 +4,7 @@
   ...
 }: let
   inherit (lib.modules) mkIf;
+  inherit (lib.strings) optionalString;
   inherit (lib.nvim.dag) entryAnywhere;
   inherit (lib.nvim.lua) toLuaObject;
 
@@ -12,13 +13,29 @@ in {
   config = mkIf (cfg.enable && cfg.lightbulb.enable) {
     vim = {
       startPlugins = ["nvim-lightbulb"];
-
       pluginRC.lightbulb = entryAnywhere ''
-        vim.api.nvim_command('autocmd CursorHold,CursorHoldI * lua require\'nvim-lightbulb\'.update_lightbulb()')
-
-        -- Enable trouble diagnostics viewer
-        require'nvim-lightbulb'.setup(${toLuaObject cfg.lightbulb.setupOpts})
+        local nvim_lightbulb = require("nvim-lightbulb")
+        nvim_lightbulb.setup(${toLuaObject cfg.lightbulb.setupOpts})
+        ${optionalString cfg.lightbulb.autocmd.enable ''
+          vim.api.nvim_create_autocmd(${toLuaObject cfg.lightbulb.autocmd.events}, {
+            pattern = ${toLuaObject cfg.lightbulb.autocmd.pattern},
+            callback = function()
+              nvim_lightbulb.update_lightbulb()
+            end,
+          })
+        ''}
       '';
     };
+
+    warnings = [
+      # This could have been an assertion, but the chances of collision is very low and asserting here
+      # might be too dramatic. Let's only warn the user, *in case* this occurs and is not intended. No
+      # error will be thrown if 'lightbulb.setupOpts.autocmd.enable' has not been set by the user.
+      (mkIf (cfg.lightbulb.autocmd.enable -> (cfg.lightbulb.setupOpts.autocmd.enabled or false)) ''
+        Both 'vim.lsp.lightbulb.autocmd.enable' and 'vim.lsp.lightbulb.setupOpts.autocmd.enable' are set
+        simultaneously. This might have performance implications due to frequent updates. Please set only
+        one option to handle nvim-lightbulb autocmd.
+      '')
+    ];
   };
 }
diff --git a/modules/plugins/lsp/lightbulb/lightbulb.nix b/modules/plugins/lsp/lightbulb/lightbulb.nix
index 4341cac6..012d54aa 100644
--- a/modules/plugins/lsp/lightbulb/lightbulb.nix
+++ b/modules/plugins/lsp/lightbulb/lightbulb.nix
@@ -1,11 +1,29 @@
 {lib, ...}: let
-  inherit (lib.options) mkEnableOption;
-  inherit (lib.nvim.types) mkPluginSetupOption;
+  inherit (lib.options) mkOption mkEnableOption;
+  inherit (lib.types) listOf str either;
+  inherit (lib.nvim.types) mkPluginSetupOption luaInline;
 in {
   options.vim.lsp = {
     lightbulb = {
       enable = mkEnableOption "Lightbulb for code actions. Requires an emoji font";
       setupOpts = mkPluginSetupOption "nvim-lightbulb" {};
+      autocmd = {
+        enable = mkEnableOption "updating lightbulb glyph automatically" // {default = true;};
+        events = mkOption {
+          type = listOf str;
+          default = ["CursorHold" "CursorHoldI"];
+          description = "Events on which to update nvim-lightbulb glyphs";
+        };
+
+        pattern = mkOption {
+          type = either str luaInline;
+          default = "*";
+          description = ''
+            File patterns or buffer names to match, determining which files or buffers trigger
+            glyph updates.
+          '';
+        };
+      };
     };
   };
 }