{ config, lib, pkgs, nix2lua, ... }: let inherit (builtins) match isFunction attrValues; cfg = config.plugins.navigation.telescope; telescopeExtensions = lib.flip lib.filterAttrs pkgs.vimPlugins (k: v: k != "telescope-nvim" && match "^.+[-_]telescope$|^telescope[-_].+$" k == [ ] ); extensions = if isFunction cfg.extensions then cfg.extensions telescopeExtensions else cfg.extensions; extensionOpts = { name, ... } @ sub: { options = with lib; with types; { name = mkOption { type = str; description = "Extension name"; }; package = mkPackageOption telescopeExtensions name { }; settings = mkOption { type = attrs; default = { }; description = "Additional configuration to setup an extension"; }; loadExtension = mkOption { type = nullOr attrs; description = "Expression to load extension"; defaultText = literalExpression ''require("telescope").load_extension("")''; }; }; config = { name = lib.mkDefault name; loadExtension = with nix2lua; lib.mkDefault (pipe1 (var config.plugin.telescope-nvim.varName) (call "load_extension" sub.config.name) ); }; }; in { options.plugins.navigation.telescope = with lib; with types; { enable = mkEnableOption "telescope"; package = mkPackageOption pkgs.vimPlugins "telescope-nvim" { }; settings = mkOption { type = attrs; default = { }; description = '' See: https://github.com/nvim-telescope/telescope.nvim?tab=readme-ov-file#customization ''; example = { pickers = { find_files = { theme = "dropdown"; }; }; }; }; extensions = mkOption { type = let extSubmodule = attrsOf (submodule extensionOpts); in oneOf [ (functionTo (extSubmodule)) extSubmodule ]; default = { }; defaultText = literalExpression "{}"; example = { telescope-live-grep-args-nvim = { name = "live_grep_args"; }; }; }; }; config = lib.mkIf cfg.enable { plugin = lib.mkMerge (lib.flatten [ { plenary-nvim = lib.mkDefault { isDependency = true; }; telescope-nvim = { name = "telescope"; package = cfg.package; setupSettings = lib.mkMerge (lib.flatten [ cfg.settings (lib.mapAttrsToList (k: v: { extensions."${v.name}" = v.settings; }) (lib.filterAttrs (k: v: v.settings != { }) extensions) ) ]); afterSetup = map (ext: ext.loadExtension) (attrValues extensions); }; } # extensions (lib.flip lib.mapAttrsToList extensions (packageName: ext: { "${packageName}" = { inherit (ext) package; isDependency = lib.mkDefault true; }; })) ]); }; }