{
  lib,
  config,
  pkgs,
  system,
  ...
}: let
  inherit (lib.snowfall.system) is-linux is-darwin;

  cfg = config.marleyos.programs.fish;
in {
  options.marleyos.programs.fish.enable = lib.mkEnableOption "fish";

  config = lib.mkIf cfg.enable {
    home.packages = with pkgs;
      [
        # general
        babelfish

        # for fish_greeting()
        marleyos.figlet-xero-fonts
        lolcat

        # for extract()
        gnutar
        bzip2
        bzip3
        gzip
        unzip
        pax
      ]
      # unrar-free is broken on darwin :(
      ++ (lib.optionals (is-linux system) [unrar-free])
      ++ (lib.optionals (is-darwin system) [unrar]);

    programs.fish = {
      enable = true;

      preferAbbrs = true;

      plugins = with pkgs.fishPlugins; [
        {
          name = "z";
          src = z;
        }
        {
          name = "Puffer Fish";
          src = puffer;
        }
        {
          name = "Sponge";
          src = sponge;
        }
        {
          name = "autopair.fish";
          src = autopair;
        }
      ];

      shellInit =
        # fish
        ''
          set -g fish_key_bindings fish_vi_key_bindings
        '';

      shellAbbrs = {
        cp = "cp -iv";
        mkdir = "mkdir -pv";
        mv = "mv -iv";
        rm = "rm -rf";
        grep = "grep --color=auto";
        # FIXME
        sail = "./vendor/bin/sail";
      };

      functions = {
        fish_greeting =
          # fish
          ''
            echo ""
            figlet -f Elite " marleyOS" | lolcat
          '';

        extract = {
          argumentNames = "file";
          body =
            # fish
            ''
              set --erase argv[1]

              if test -f "$file"
                switch "$file"
                  case "*.tar.bz2"
                    tar -jxvf $argv $file

                  case "*.tar.gz"
                    tar -zxvf $argv $file

                  case "*.bz2"
                    bunzip2 $argv $file

                  case "*.bz3"
                    bunzip3 $argv $file

                  case "*.gz"
                    gunzip $argv $file

                  case "*.tar"
                    tar -xvf $argv $file

                  case "*.tbz2"
                    tar -jxvf $argv $file

                  case "*.tgz"
                    tar -zxvf $argv $file

                  case "*.zip" "*.ZIP"
                    unzip $argv $file

                  case "*pax"
                    cat $file | pax -r $argv

                  case "*.pax.Z"
                    uncompress $file --stdout | pax -r $argv

                  case "*.rar"
                    unrar-free $file

                  case "*.Z"
                    uncompress $argv $file

                  case "*"
                    echo "'$file' cannot be extracted via extract()."
                end
              else
                echo "'$file' is not a valid file."
              end
            '';
        };
      };
    };
  };
}
