nixvim
                                
                                 nixvim copied to clipboard
                                
                                    nixvim copied to clipboard
                            
                            
                            
                        Provide custom telescope extension
I use nixvim.homeManagerModules.nixvim in my dotfiles homeManager-managed repo.
I'd like to be able to create a telescope extension and enable it.
My idea was to use mkExtension (which I didn't find a way to access from my dotfiles repo, but I was happy to copy it in my repo) to create my-telescope-extension with defaultPackage being a local .lua file as the actual telescope extension I want to port to nixvim, and then pass it in telescope.settings.extension.{my-telescope-extension.enable=true;}.
But this suggests that the extension needs to actually be part of nixvim repo, is that correct?
Because if so, it feels like the approach used for extensions is conceptually different than for other configs e.g. mappings, i.e. you can provide your own key mappings, but not your extensions, they must be part of the repo itself.
If the above is true, could I instead override in my flake.nix (below) the nixvim input to essentially inject plugins/telescope/extensions/my-telescope-extension.nix ?
I understand this one is a rather nix question not nixvim per se, but still I thought I can ask here.
Also I know I could probably fork nixvim repo, add my-telescope-extension.nix file, then supply my fork in the inputs.nixvim.url, but I don't like that pattern.
inputs = {
	# snip
	# can I override this and essentially inject a file inside the plugins/telescope/extensions dir ?
	nixvim = {  url = "github:nix-community/nixvim/main"; inputs.nixpkgs.follows = "nixpks"; };
}
I could also supply this in the nixvim config:
extraPlugins = [ pkgs.my-overlays.my-telescope-extension ];
extraConfigLua = ''  require("my-telescope-extension").setup() '';
because in my flake.nix I add my-overlays on top of nixpkgs.
But not as nixvim-native of a solution as it could be. Thoughts?
Just to show what I expected to be able to do inside a local dotfiles repo. I'm only including the relevant parts.
# flake.nix
{
	inputs = {
		# ...
		nixvim = {
			url = "github:nix-community/nixvim/main";
			inputs.nixpkgs.follows = "nixpkgs";'
		};
	};
	outputs = {self, nixpkgs, homeManager, nixvim}: {
		homeConfigurations {
			"me" = homeManager.lib.homeManagerConfiguration {
			inherit pkgs;
			modules = [
			      ./my-hm-pkgs.nix
			      {
			         home = { ... };
			      }
				  nixvim.homeManagerModules.nixvim
			];
			    # just something to allow me to access nixvim below because otherwise I don't know how
			    extraSpecialArgs = { inherit nixvim; };
			};
		};
	};
}
# my-hm-pkgs.nix
{
 pkgs,
 config,
 nixvim, # passed via the extraSpecialArgs above in homeManager.lib.homeManagerConfiguration
 ...	
} : {
	
  programs = {
	  # ... 
	  nixvim = import my-nixvim-config.nix {
	  		inherit pkgs config nixvim; # I pass it down again
	  };
  };
}
This is the config file I pass to programs.nixvim:
# my-nixvim-config.nix
{
	pkgs,
	config,
	nixvim, # passed all the way via homeManager.lib.homeManagerConfiguration extraSpecialArgs
}: {
	plugins = {
		telescope = {
			enable=true;
			settings = {
				extensions = {
					myTelescopeExtension = (import ./telescope/extensions.nix {
						inherit pkgs config nixvim;
					}).myTelescopeExtension;
				}
			}
		}
	}
}
# telescope/extensions.nix
{
	pkgs,
	config,
	nixvim, # passed all the way via homeManager.lib.homeManagerConfiguration extraSpecialArgs
}: let 
	# here I try to grab nixvim's helpers. that's why I've been passing it down so far
	helpers = (nixvim.homeManagerModules.nixvim {
			inherit pkgs config;
			lib = pkgs.lib;
		})
		.options
		.nixvim
		.helpers
		.default;
	# This local ./mkExtension.nix file is a copy of nixvim repo plugins/telescope.extensions/_helpers.nix file.
	# the reason why I copied it is because I didn't find a way to access it otherwise
	# e.g. with an `nixvim.something.something._helpers.mkExtension` syntax
	mkExtension = import ./mkExtension.nix {
		inherit helpers;
		lib = pkgs.lib; # I think this is wrong, because it should be nixvim's lib, but I don't know how to access that
		config = {
			plugins = {
				telescope = {
					enable = true;
					extensions = {
						myTelescopeExtension = {
							enable = true;
							package = {};
							settings = {};
						};
					};
				};
			};
		};
	};	
	# here I call your mkExtension function
	myTelescopeExtension = mkExtension.mkExtension {
		name = "myTelescopeExtension";
		# I just tried one that already exists, but in reality I'd put my own here
		defaultPackage = pkgs.vimPlugins.telescope-ui-select-nvim;
	};
} in {
	inherit myTelescopeExtension;
}
Now running home-manager fails with a segmentation fault.
home-manager switch --flake path:$HOME...
fails with
line 536 Segmentation fault    nix build "${extraArgs[@]}"  "${PASSTHROUGH_OPTS[@]}"
But this is the pattern I'd like to use because I think it's very clean and allows the end user to easily declare a Telescope extension.
But as per my first message, it doesn't look like mkExtension function is designed to be used this way.
In the end what I've done is create a plugin with pkgs.vimUtils.buildVimPlugin, then pass it to nixvim's config in:
extraPlugins = [ my-telescope-extension ];
extraConfigLua = ''  require("my-telescope-extension").setup() '';
The first part (i.e. creating the plugin with pkgs.vimUtils.buildVimPlugin) has to be done anyway, but would be nice to register it via plugins.telescope rather than via extraPlugins, as per my initial idea.
Thank you @aidigital for this very detailed proposal.
I agree with your latest message. What we could definitely do is to adapt the plugins.telescope module to allow users to add arbitrary extensions in the form of a derivation.
I think that this is definitely a good idea, so I will re-open this issue.
The first part (i.e. creating the plugin with
pkgs.vimUtils.buildVimPlugin) has to be done anyway, but would be nice to register it viaplugins.telescoperather than viaextraPlugins, as per my initial idea.
Is there a way to know which string to pass to require('telescope').load_extension from a vimPlugin derivation? Or a way to know if the plugin's setup function loads its telescope extension automatically, without the user manually calling load_extension?
If not, we probably won't be able to do anything useful by adding a plugin derevation to a telescope extension list.
I don't think guessing based on the plugin's name is the best option, unless almost all plugins follow that pattern.
For now, I'm proposing we make enabledExtensions public, so that users can manually add a plugin to extraPackages and the extension name to plugins.telescope.enabledExtensions, without having to expilcitly use require('telescope').load_extension themselves.
Maybe in the future we could extend that option type to either str or package, and assume if a package is used that the package name matches the extension name expected by load_extension?