_: {
  programs.bash.bashrcExtra = ''
    # Quick directory creation and navigation
    mkcd() {
        mkdir -p "$1" && cd "$1"
    }

    # Extract various archive formats
    extract() {
        for archive in "$@"; do
            if [ -f "$archive" ]; then
                case "$archive" in
                *.tar.bz2) tar xvjf "$archive" ;;
                *.tar.gz) tar xvzf "$archive" ;;
                *.bz2) bunzip2 "$archive" ;;
                *.rar) unrar x "$archive" ;;
                *.gz) gunzip "$archive" ;;
                *.tar) tar xvf "$archive" ;;
                *.tbz2) tar xvjf "$archive" ;;
                *.tgz) tar xvzf "$archive" ;;
                *.zip) unzip "$archive" ;;
                *.Z) uncompress "$archive" ;;
                *.7z) 7z x "$archive" ;;
                *) echo "don't know how to extract '$archive'..." ;;
                esac
            else
                echo "'$archive' is not a valid file!"
            fi
        done
    }

    # Find files quickly
    ff() {
        find . -name "*$1*" -type f
    }

    # Find directories quickly
    fd() {
        find . -name "*$1*" -type d
    }

    # IP address lookup
    alias whatismyip="whatsmyip"
    function whatsmyip () {
        # Internal IP Lookup.
        if command -v ip &> /dev/null; then
            echo -n "Internal IP: "
            ip addr show wlan0 | grep "inet " | awk '{print $2}' | cut -d/ -f1
        else
            echo -n "Internal IP: "
            ifconfig wlan0 | grep "inet " | awk '{print $2}'
        fi

        # External IP Lookup
        echo -n "External IP: "
        curl -4 ifconfig.me
    }

    # Searches for text in all files in the current folder
    ftext() {
      # -i case-insensitive
      # -I ignore binary files
      # -H causes filename to be printed
      # -r recursive search
      # -n causes line number to be printed
      # optional: -F treat search term as a literal, not a regular expression
      # optional: -l only print filenames and not the matching lines ex. grep -irl "$1" *
      grep -iIHrn --color=always "$1" . | less -r
    }

    # Copy file with a progress bar
    cpp() {
      set -e
      strace -q -ewrite cp -- "$1" "$2" 2>&1 |
      awk '{
          count += $NF
          if (count % 10 == 0) {
              percent = count / total_size * 100
              printf "%3d%% [", percent
              for (i=0;i<=percent;i++)
                  printf "="
              printf ">"
              for (i=percent;i<100;i++)
                  printf " "
              printf "]\r"
          }
      }
      END { print "" }' total_size="$(stat -c '%s' "$1")" count=0
    }

    # Copy and go to the directory
    cpg() {
      if [ -d "$2" ]; then
        cp "$1" "$2" && cd "$2"
      else
        cp "$1" "$2"
      fi
    }

    # Move and go to the directory
    mvg() {
      if [ -d "$2" ]; then
        mv "$1" "$2" && cd "$2"
      else
        mv "$1" "$2"
      fi
    }

    # Create and go to the directory
    mkdirg() {
      mkdir -p "$1"
      cd "$1"
    }

    # Goes up a specified number of directories  (i.e. up 4)
    up() {
      local d=""
      limit=$1
      for ((i = 1; i <= limit; i++)); do
        d=$d/..
      done
      d=$(echo $d | sed 's/^\///')
      if [ -z "$d" ]; then
        d=..
      fi
      cd $d
    }

    # Automatically do an ls after each cd, z, or zoxide
    cd ()
    {
      if [ -n "$1" ]; then
        builtin cd "$@" && ls
      else
        builtin cd ~ && ls
      fi
    }

    # Returns the last 2 fields of the working directory
    pwdtail() {
      pwd | awk -F/ '{nlast = NF -1;print $nlast"/"$NF}'
    }
  '';
}
