[home-manager] make fish plugins actually load

Hi everyone!

I’m confused about the state of fish plugin support in home-manager and nixos in general. I’m quite new to nixos so I might misunderstand some concepts. Especially provided I’ve seen other people’s configs and they don’t seem to have such issues at all.

The issue is as follows: plugins are installed properly but they aren’t loaded. What I’ve done is actually loading them by hand one by one. Here’s the part of my nixos config responsible for the fish shell.

{ config, lib, pkgs, utils, ... }:

let 
  user = config.home-manager.users.heinwol;
in
{   
  programs.fish = {
    enable = true;
# as one can see vendor stuff is indeed enabled, though nothing loads
    vendor = {
      completions.enable = true;
      config.enable = true;
      functions.enable = true;
    };
  };   

    home-manager.users.heinwol = {
      programs.fish = let
        source_plugin = (plugin_name: plugin_src:
          let
            source_dir = dir_name:
              ''
                if test -d ${plugin_src}/share/fish/${dir_name}
                    for file in ${plugin_src}/share/fish/${dir_name}/*.fish
                        source $file
                    end
                end
              ''; 
          in
          ''
            source ${user.xdg.configHome}/fish/conf.d/plugin-${plugin_name}.fish
            ${source_dir "vendor_functions.d"}
            ${source_dir "vendor_completions.d"}
            ${source_dir "vendor_conf.d"}
            ${source_dir "vendor_themes.d"}
          ''
          );
      
        plugins.theme-kawasaki = pkgs.fetchFromGitHub {
          owner = "hastinbe";
          repo = "theme-kawasaki";
          rev = "master";
          hash = "sha256-BdV4FtHBDBdERb9t2xQ9gQ0MiymE1ls8WNGBToZtqnE=";
        };
        plugins.plugin-jump = pkgs.fetchFromGitHub {
          owner = "oh-my-fish";
          repo = "plugin-jump";
          rev = "master";
          hash = "sha256-MVIXBKsfd7rrH7Dh7cksNI29YunqAGZvuZwdfrf1bZQ=";
        };
        plugins.fzf-fish = pkgs.fishPlugins.fzf-fish;
        plugins.autopair = pkgs.fishPlugins.autopair;
        plugins.colored-man-pages = pkgs.fishPlugins.colored-man-pages;
      in {
          enable = true;
          plugins = lib.mapAttrsToList
            (name: value: {name = name; src = value;})
            plugins;
          interactiveShellInit = lib.strings.concatStrings (lib.strings.intersperse "\n" (lib.flatten [
            (builtins.readFile ../config/fish/config.fish)
          ]));
          shellInit = lib.strings.concatStrings (lib.strings.intersperse "\n" (lib.flatten [
            (lib.mapAttrsToList source_plugin plugins)
          ]));
        };

      # needed for fzf-fish to work
      programs.fzf.enableFishIntegration = false;

      home.packages = with pkgs; [
        fish
      ];

    };
  }

And It works! But I don’t get why isn’t there any option to load all of the plugins automatically. What am I missing? How is it supposed to be done? Maybe the problem with my knowledge of fish and there’s some function called e.g. load_all_plugins which can be simply put into config.fish and it will do it for me?

1 Like

Hi friend, I’ve had the same issue. It’s not very clearly documented tbh, but all you need to do is specify the src property of the plugin packages in fish.plugins, i.e.:

{ config, lib, pkgs, utils, ... }:
let
  user = config.home-manager.users.heinwol;
in
{
  programs.fish = {
    enable = true;
    vendor = {
      completions.enable = true;
      config.enable = true;
      functions.enable = true;
    };
  };

  home-manager."${user}" = {
    programs.fish = {
      enable = true;
      # For your git dependencies, just proceed as usual
      plugins = with pkgs.fishPlugins; [
        fzf-fish.src
        autopair.src
        colored-man-pages.src
      ];
    };
    programs.fzf.enableFishIntegration = false;

    home.packages = with pkgs; [
      fish
    ];
  };
};

You’ll note that the init scripts, which are automatically generated by home-manager in $HOME/.config/fish/conf.d/plugin-<PLUGIN_NAME>.fish, expect the plugins store directory to contain the subdirectories functions/, completsions/, conf.d/, where conf.d should hold all initialization code. You’ll find these directories in the packaged plugins at the fishPlugins.<NAME>.src attribute, but not in the main package.

Hope that helps.

1 Like