{
  config,
  lib,
  pkgs,
  ...
}: let
  inherit (lib) mkIf;
  hasPackage = pname: lib.any (p: p ? pname && p.pname == pname) config.home.packages;
  hasRipgrep = hasPackage "ripgrep";
  hasExa = hasPackage "eza";
  hasNeovim = config.programs.neovim.enable;
  hasLazygit = config.programs.lazygit.enable;
  hasLazydocker = hasPackage "lazydocker";
  hasNixYourShell = hasPackage "nix-your-shell";
  hasShellColor = config.programs.shellcolor.enable;
  shellcolor = "${pkgs.shellcolord}/bin/shellcolor";
in {
  programs.fish = {
    enable = true;
    interactiveShellInit = ''
      ${
        if hasNixYourShell
        then "nix-your-shell fish | source"
        else ""
      }
    '';
    plugins = [
      {
        name = "grc";
        src = pkgs.fishPlugins.grc.src;
      }
      {
        name = "fzf";
        src = pkgs.fishPlugins.fzf.src;
      }
      {
        name = "tide";
        src = pkgs.fishPlugins.tide.src;
      }
      {
        name = "sponge";
        src = pkgs.fishPlugins.sponge.src;
      }
      {
        name = "autopair";
        src = pkgs.fishPlugins.autopair.src;
      }
    ];
    shellAliases = {
      lzg = mkIf hasLazygit "lazygit";
      lzd = mkIf hasLazydocker "lazydocker";
      batt = ''upower -i /org/freedesktop/UPower/devices/battery_BAT0 | grep -e "percentage" -e "state"'';
      hx = "~/Documents/heliox-cli/target/debug/heliox-cli --mode";
      slp = "systemctl suspend";
      sdn = "shutdown 0";
    };
    shellAbbrs = rec {
      jqless = "jq -C | less -r";

      n = "nix";
      nd = "nix develop -c $SHELL";
      ns = "nix shell";
      nsn = "nix shell nixpkgs#";
      nb = "nix build";
      nbn = "nix build nixpkgs#";
      nf = "nix flake";

      nr = "nixos-rebuild --flake .";
      nrs = "nixos-rebuild --flake . switch";
      snr = "sudo nixos-rebuild --flake .";
      snrs = "sudo nixos-rebuild --flake . switch";
      hm = "home-manager --flake .";
      hms = "home-manager --flake . switch";

      ls = mkIf hasExa "eza";
      exa = mkIf hasExa "eza";

      vim = mkIf hasNeovim "nvim";
      vi = vim;
      v = vim;
    };
    functions = {
      # Disable greeting
      fish_greeting = "";
      fish_init_custom = ''
        #Variable names: https://github.com/IlanCosman/tide/blob/main/functions/tide/configure/configs/rainbow.fish
        #Tide base
        tide configure --auto --style=Rainbow --prompt_colors='True color' --show_time=No --rainbow_prompt_separators=Vertical --powerline_prompt_heads=Slanted --powerline_prompt_tails=Flat --powerline_prompt_style='Two lines, frame' --prompt_connection=Solid --powerline_right_prompt_frame=No --prompt_connection_andor_frame_color=Darkest --prompt_spacing=Compact --icons='Many icons' --transient=Yes

        #OS module
        set tide_os_bg_color ${config.colorScheme.colors.base07}

        #PWD module
        set tide_pwd_bg_color ${config.colorScheme.colors.base0D}
        set tide_pwd_color_dirs ${config.colorScheme.colors.base02}
        set tide_pwd_color_truncated_dirs ${config.colorScheme.colors.base04}
        set tide_pwd_color_anchors ${config.colorScheme.colors.base02}

        #Git module
        set tide_git_bg_color ${config.colorScheme.colors.base0B}
        set tide_git_bg_color_unstable ${config.colorScheme.colors.base0A}
        set tide_git_bg_color_urgent ${config.colorScheme.colors.base08}
      '';
    };
  };
  home.packages = with pkgs; [grc fzf nix-your-shell];

  # Applies tide configure on rebuild
  home.activation.configureTide = lib.hm.dag.entryAfter ["writeBoundary"] ''
    ${pkgs.fish}/bin/fish -c "fish_init_custom"
  '';
}