{
  # Snowfall Lib provides a customized `lib` instance with access to your flake's library
  # as well as the libraries available from your flake's inputs.
  lib,
  # An instance of `pkgs` with your overlays and packages applied is also available.
  pkgs,
  # You also have access to your flake's inputs.
  inputs,

  # Additional metadata is provided by Snowfall Lib.
  system, # The system architecture for this host (eg. `x86_64-linux`).
  target, # The Snowfall Lib target for this system (eg. `x86_64-iso`).
  format, # A normalized name for the system target (eg. `iso`).
  virtual, # A boolean to determine whether this system is a virtual target using nixos-generators.
  systems, # An attribute map of your defined hosts.

  # All other arguments come from the module system.
  config,
  ...
}:

with lib;

let
  cfg = config.modules.shell.fish;
in
{
  options.modules.shell.fish = {
    enable = mkOption { default = false; };
  };

  config = mkIf cfg.enable {

    home.file = {
      ".config/starship.toml".source = ./starship.toml;
      ".config/fish/conf.d/last-working-dir.fish".source = ./last-working-dir.fish;
    };

    home.packages = with pkgs; [ starship ];

    home.shellAliases = {
      g = "git status";
      fd = "fd -HI";
      ls = "ls --color";
      la = "ls -Alh --color";
      grep = "grep --color";
      conf = "edit-config";
      c = "fzf-z";
    };

    programs.starship = {
      enable = true;
      enableFishIntegration = true;
    };

    programs.fish = {
      enable = true;

      interactiveShellInit = "set fish_greeting"; # Disable default greeting

      plugins = [
        {
          name = "z";
          src = pkgs.fishPlugins.z.src;
        }
      ];

      functions = {
        fzf-z = ''
          set dir $(z --list | fzf --tiebreak=index | sed -E 's/^[0-9\.]+[[:space:]]+//')
          cd $dir
        '';
        mkcd = ''
          mkdir $argv
          cd $argv
        '';
        run = ''
          nix run nixpkgs#"$argv[1]" -- $argv[2..-1]
        '';
        shell = ''
          set args
          for arg in $argv
              set args $args nixpkgs#$arg
          end
          nix shell $args
        '';
      };
    };
  };
}