{ lib, writeShellScriptBin, fish }:

with lib;

makeOverridable ({
  completionDirs ? [],
  functionDirs ? [],
  confDirs ? [],
  pluginPkgs ? []
}:

let
  vendorDir = kind: plugin: "${plugin}/share/fish/vendor_${kind}.d";
  complPath = completionDirs ++ map (vendorDir "completions") pluginPkgs;
  funcPath = functionDirs ++ map (vendorDir "functions") pluginPkgs;
  confPath = confDirs ++ map (vendorDir "conf") pluginPkgs;

in writeShellScriptBin "fish" ''
  ${fish}/bin/fish --init-command "
    set --prepend fish_complete_path ${escapeShellArgs complPath}
    set --prepend fish_function_path ${escapeShellArgs funcPath}
    set --local fish_conf_source_path ${escapeShellArgs confPath}
    for c in \$fish_conf_source_path/*; source \$c; end
  " "$@"
'')

{ lib, writeShellScriptBin, fish, writeTextFile }:

lib.makeOverridable ({
  completionDirs ? [],
  functionDirs ? [],
  confDirs ? [],
  pluginPkgs ? [],
  localConfig ? "",
  shellAliases ? {}
}:

let
  aliasesStr = builtins.concatStringsSep "\n"
      (lib.mapAttrsToList (k: v: "alias ${k} ${lib.escapeShellArg v}") shellAliases);

  shellAliasesFishConfig = writeTextFile {
    name = "wrapfish.aliases.fish";
    destination = "/share/fish/vendor_conf.d/aliases.fish";
    text = ''
      status --is-interactive; and begin
        # Aliases
        ${aliasesStr}
      end
    '';
  };

  localFishConfig = writeTextFile {
    name = "wrapfish.local.fish";
    destination = "/share/fish/vendor_conf.d/config.local.fish";
    text = localConfig;
  };

  vendorDir = kind: plugin: "${plugin}/share/fish/vendor_${kind}.d";
  complPath = completionDirs ++ map (vendorDir "completions") pluginPkgs;
  funcPath = functionDirs ++ map (vendorDir "functions") pluginPkgs;
  confPath = confDirs
    ++ (map (vendorDir "conf") pluginPkgs)
    ++ (map (vendorDir "conf") [ localFishConfig shellAliasesFishConfig ]);

in writeShellScriptBin "fish" ''
  ${fish}/bin/fish --init-command "
    set --prepend fish_complete_path ${lib.escapeShellArgs complPath}
    set --prepend fish_function_path ${lib.escapeShellArgs funcPath}
    set --local fish_conf_source_path ${lib.escapeShellArgs confPath}
    for c in \$fish_conf_source_path/*; source \$c; end
  " "$@"
'')

Add `localConfig` and `shellAliases` parameters.
wrapFish: Add `localConfig` and `shellAliases` parameters.
