# vi:syntax=bash

# Heavily inspired from https://github.com/sorin-ionescu/prezto/blob/master/modules/git/alias.zsh
# Git aliases
# Log
zstyle -s ':prezto:module:git:log:medium' format '_git_log_medium_format' \
  || _git_log_medium_format='%C(bold)Commit:%C(reset) %C(green)%H%C(red)%d%n%C(bold)Author:%C(reset) %C(cyan)%an <%ae>%n%C(bold)Date:%C(reset)   %C(blue)%ai (%ar)%C(reset)%n%w(80,1,2)%+B'
zstyle -s ':prezto:module:git:log:oneline' format '_git_log_oneline_format' \
    || _git_log_oneline_format='%C(green)%h%C(reset) %><(55,trunc)%s%C(red)%d%C(reset) %C(blue)[%an]%C(reset) %C(yellow)%ad%C(reset)%n'
zstyle -s ':prezto:module:git:log:brief' format '_git_log_brief_format' \
  || _git_log_brief_format='%C(green)%h%C(reset) %s%n%C(blue)(%ar by %an)%C(red)%d%C(reset)%n'

# Status
zstyle -s ':prezto:module:git:status:ignore' submodules '_git_status_ignore_submodules' \
  || _git_status_ignore_submodules='none'

# Aliases

# Branch (b)
alias gb='git branch'
alias gba='git rev-parse --abbrev-ref HEAD'
alias gbc='git checkout -b'
alias gbx='git branch -d'
alias gbX='git branch -D'
# Show the differences of the current head since it diverged from master
function gbd (){
    git diff $(git merge-base master HEAD)...HEAD
}
function gbds (){
    git diff --stat $(git merge-base master HEAD)...HEAD
}
alias gdiff='git diff --no-index'

# Commit (c)
alias gc='git commit --verbose'
alias gcam='git commit --verbose --amend'
alias ga='git add'
alias gcu='git add -u; git commit --verbose'
alias gca='git add -A; git commit --verbose'
alias gco='git checkout'
gcoo() {
    if [[ "$#" -eq 0 ]]; then
        local FILES=(${(f)"$(git diff --name-only| fzf --multi --reverse)"})
        for FILE in ${FILES[@]}; do
            git checkout "$FILE"
        done
    else
        git checkout "$@"
    fi
}
gsq() {
    if [[ "$#" -ne 1 ]]; then
        echo "requires an int arg representing number of commits"
    fi
    MSG=$(git log --format=%B HEAD~"${1}"..HEAD)
    git reset --soft HEAD~"${1}"
    git commit --verbose --edit -m"${MSG}"
}
gfo() {
    git commit -m 'temp'
    MSG=$(git log --format=%B HEAD~2..HEAD~1)
    git reset --soft HEAD~"2"
    git commit --verbose --edit -m"${MSG}"
}
alias gcp='git cherry-pick --ff'
alias gcm='git commit --amend'

# Fetch (f)
alias gf='git fetch'
alias gfc='git clone'

# Log (l)
alias gl='git log --topo-order --pretty=format:${_git_log_medium_format}'
alias glp='git log --topo-order --pretty=format:${_git_log_medium_format} -p'
alias gls='git log --topo-order --stat --pretty=format:${_git_log_medium_format}'
alias gld='git log --topo-order --stat --patch --full-diff --pretty=format:${_git_log_medium_format}'
alias glo='git log --topo-order --date=local --pretty=format:${_git_log_oneline_format}'
# sed will remove multiple adjacent whitespaces
alias glg='git log --topo-order --all --graph --date=local --pretty=format:${_git_log_oneline_format}'
alias glb='git log --topo-order --pretty=format:${_git_log_brief_format}'
alias glc='git shortlog --summary --numbered'

# Rebase (r)
alias gr='git rebase'
alias gra='git rebase --abort'
alias grc='git rebase --continue'
alias gri='git rebase --interactive'
alias grs='git rebase --skip'

# Merge (m)
alias gm='git merge'

# Push (p)
alias gp='git push'
alias gpl='git fetch origin master && git rebase origin/master'

# Stash (s)
alias gs='git stash'
alias gsa='git stash apply'
alias gsx='git stash drop'
alias gsX='git-stash-clear-interactive'
alias gsl='git stash list'
alias gss='git stash save --include-untracked'

# Working Copy (w)
alias gws='git status --ignore-submodules=${_git_status_ignore_submodules} --short'
alias gwS='git status --ignore-submodules=${_git_status_ignore_submodules}'
alias gwd='git diff --no-ext-diff'
alias gwsd='git diff --cached'
alias gwD='git diff --no-ext-diff --word-diff'
alias gwr='git reset'
alias gwR='git reset --hard'
alias gwc='git clean -f'
gwu() {
    local FILES=(${(f)"$(git ls-files --others --exclude-standard| fzf --multi --reverse)"})
    for FILE in ${FILES[@]}; do
        rm "$FILE"
    done
}
alias gcp='git cherry-pick --ff'


# Personal Aliases
alias s='ssh'
alias n='nvim'
alias ks='kitty +kitten ssh'
alias sco='nvim ~/.ssh/config'
alias nvimf='nvim $(fzf)'
alias cdf='cd $(find . -type d | fzf)'
alias ..='cd ../'
alias ...='cd ../../'
alias ....='cd ../../../'
alias t='tmux'
alias ta='tmux attach'
alias tre='~/.tmux/window_renum.sh'
alias ncdu='ncdu --color dark -x'
alias rcp='rsync --verbose --progress --human-readable -zz --archive --hard-links --one-file-system'
alias rmv='rsync --verbose --progress --human-readable -zz --archive --hard-links --one-file-system --remove-source-files'
alias rmvu='rsync --verbose --progress --human-readable -zz --archive --hard-links --one-file-system --remove-source-files --update'
alias rsynchronize='rsync --verbose --progress --human-readable --compress --archive --hard-links --one-file-system --remove-source-files --update --delete'


###########
# Functions
###########

# Color shortcuts
G="\e[32m"
R="\e[31m"
C="\e[36m"
NC="\e[39m"

# Docker functions
alias dl="docker logs"
alias dlf="docker logs --follow"
dpa() { docker ps -a } # List all containers
di() { docker images } # Show images
drm() { docker rm $(docker ps -a -q) 2> /dev/null; } # Remove dead containers
drv() { docker volume rm $(docker volume ls -qf dangling=true) } # remove dangling volumes
dri() { docker rmi -f $(docker images -q) } # Remove unused images
dstop() { docker stop $(docker ps -a -q); } # Stop all containers
dip() { docker inspect --format '{{ .NetworkSettings.IPAddress }}' "$1" }
dfp() { # Function to get forwarded port of docker container
  if [ -z "$2" ]; then
    docker inspect --format='{{(index (index .NetworkSettings.Ports "8000/tcp") 0).HostPort}}' $1
  else
    docker inspect --format='{{(index (index .NetworkSettings.Ports "'$2'/tcp") 0).HostPort}}' $1
  fi
}
dfpo() { # Open chrome to a forwarded container port
  if [ "$#" -ne 1 ]; then
      echo 'Usage: dfpo $port'
  else
      /usr/bin/open -a '/Applications/Google Chrome.app' 'http://localhost:'"$1"
  fi
}
dex() { # Enter a container
  if [ -z "$2"]; then
    docker exec -it "$1" /bin/bash
  else
    docker exec -it "$1" "$2"
  fi
}


# Tmux functions
t4() {
    tmux split-window
    tmux split-window
    tmux split-window
    tmux select-layout tiled
}
tat() { # Creating a second window on a session
  if [ ! -z "$1" ]; then
    tmux new -t "$1" -s "$1"1
  fi
}
tla() {
    if [[ -z "$1" ]]; then
        return
    fi
    # Search in all folders under 'Work'
    local PROJS=($(find "$HOME"/Work/* -mindepth 1 -maxdepth 1 -type d))
    local PROJ_NAME=''
    local PROJ_DIR=''
    # Find if we have a match
    for dir in "${PROJS[@]}"; do
        if [[ $(basename "$dir") == "$1" ]]; then
            PROJ_NAME=$(basename "$dir")
            PROJ_DIR="$dir/code"
        fi
    done
    if [[ -z "$PROJ_NAME" ]]; then
        echo 'Project not found'
        return
    fi
    PROJECT="$PROJ_NAME" DIR="$PROJ_DIR" tmuxp load ~/.tmux/templates/alternative.yaml
}

# Nixos
alias nrs="sudo -i nixos-rebuild switch"
alias nco="sudo nixos-container"
alias ns="nix-shell -p"

# Git
gup() { # Loop through args, branches, and update them
    orig_head="$(git name-rev --name-only HEAD)"
    for var in "$@"
    do
        git checkout "$var"
        git pull origin "$var"
        git merge origin/"$var"
    done
    git checkout "$orig_head"
}

gupr() {
    git checkout "$1"
    git fetch origin master
    git rebase origin/master
}

gpf() {
    current_branch="$(git name-rev --name-only HEAD)"
    git push origin "$current_branch" --force
}

gpu() {
    current_branch="$(git name-rev --name-only HEAD)"
    git fetch origin "$current_branch"
    git reset --hard origin/"$current_branch"
}


# GPG
gpgen() { # Function for compressing and encrypting a file
  tar -zc $1 | gpg --encrypt --sign --armor --recipient cody@hiar.ca > $2
}
gpgde() { # Function for uncompressing and decrypting a file
  gpg -d $1 | tar -zx
}


# SSH
sl() { # Handy ssh forwarding commands, pull a port down
    if [ $# -eq 0 ]; then
        echo 'Usage: sl $host $port $bindingaddress(optional)'
    else
        while true
        do
            if [ -z "$3"]; then
                ssh -nNT -L "$2":localhost:"$2" "$1"
            else
                ssh -nNT -L "$2":"$3":"$2" "$1"
            fi
            sleep 10
        done &
    fi
}
sr() { # Handy ssh forwarding commands, push a port up
    if [ $# -eq 0 ]; then
        echo 'Usage: sl $host $port $bindingaddress(optional)'
    else
        while true
        do
            if [ -z "$3"]; then
                ssh -nNT -R "$2":localhost:"$2" "$1"
            else
                ssh -nNT -R "$2":"$3":"$2" "$1"
            fi
        done &
    fi
}


pgdumpr() { # Dump remote postgres database.
    ssh -t "$1" "sudo -u postgres bash -c \"pg_dump --no-acl --no-owner -d "$2" > /tmp/"$2"-$(date +%F).sql\""
    scp "$1":/tmp/"$2"-$(date +%F).sql .
}
pgimport() { # SCP file remotely and import it.
    scp "$2" "$1":/tmp
    SHORTNAME=$(echo "$2" | cut -d'-' -f1)
    ssh -t "$1" "sudo -u postgres bash -c \"psql -d "$SHORTNAME" < /tmp/"$2"\""
}
pgls() { # List commands on a server
    HOST="$1"
    ssh -tt "$HOST" 'sudo -u postgres bash -c "psql --list"'
}
mysqldumpr() { # Dump remote mysql database
    ssh -t "$1" "mysqldump "$2" > /tmp/"$2"-$(date +%F).sql" && scp "$1":/tmp/"$2"-$(date +%F).sql .
}
fwkill() { # Kill all of the forwarded ports on the machine
    ps aux | grep 'ssh -nNT -L' | grep -v 'grep' | awk '{ print $2 }' | xargs -n 1 kill
}
j() { # Jump to project code
    PROJ=$(find "$HOME/Work" -mindepth 2 -maxdepth 2 -type d -name "$1")
    if [[ -d "$PROJ/code" ]]; then
        cd "$PROJ/code"
    fi
}
ch() { # Force ownership on a projects files. Sometimes docker generates root owned files
    PROJ=$(find "$HOME/Work" -mindepth 2 -maxdepth 2 -type d -name "$1")
    sudo chown -R thorny:users "$PROJ/code"
}
finalurl() { # check that redirects are properly happening
    curl http://"$1" -s -L -o /dev/null -w '%{url_effective}'
    echo ''
    curl http://www."$1" -s -L -o /dev/null -w '%{url_effective}'
    echo ''
    curl https://"$1" -s -L -o /dev/null -w '%{url_effective}'
    echo ''
    curl https://www."$1" -s -L -o /dev/null -w '%{url_effective}'
    echo ''
}
newproj() { # Create a new cookiecuter project
    cookiecutter https://git.codyhiar.com/docker/cookiecutter-docker
    PROJECT=$(ls -t1 --color=never | head -1)
    mv "$PROJECT" code
    mkdir "$PROJECT"
    mv code "$PROJECT"
}
p() { # List all projects
    find "$HOME"/Work/* -mindepth 1 -maxdepth 1 -type d | xargs -n1 basename | sort
}
ssl() {
    echo | openssl s_client -servername "$1" -connect "$1":443 2>/dev/null | openssl x509 -noout -issuer -dates -subject -fingerprint
}

gfcc () {
    # This function assumes urls of one of the following formats. All others
    # will not work:
    #
    # git@github.com:user/repo.git
    # https://github.com/user/repo
    PROTOCOL=$(echo "$1" | cut -c1-3)
    if [[ "$PROTOCOL" == 'git' ]]; then
        REPO=$(echo "$1" | cut -d'/' -f2 | cut -d'.' -f1)
    elif [[ "$PROTOCOL" == 'htt' ]]; then
        REPO=$(echo "$1" | cut -d'/' -f5 )
    fi
    git clone "$1" "$REPO"/code
}

heartbeat() { # Keep a heartbeat on a website
    while true; do
        STATUS=$(nice curl -I "$1" 2> /dev/null | grep '200 OK')
        if [[ -n $STATUS ]]; then
            echo -e "$(date) ${G}$1 is up${NC}"
        else
            STATUS=$(nice curl -I "$1" 2> /dev/null | grep 'HTTP/2 200')
            if [[ -n $STATUS ]]; then
                echo -e "$(date) ${G}$1 is up${NC}"
            else
                echo -e "$(date) ${R}$1 is down${NC}"
            fi
        fi
        sleep 2
    done
}
mvw() { # i3 move workspace to monitor
    i3-msg "workspace ${1}, move workspace to output ${2}"
}
getip() { # Get ip for website, ignore cloudflare ips
    IS_CLOUDFLARE=$(dig +short NS "$1" | grep 'cloudflare')
    if [[ -n "$IS_CLOUDFLARE" ]]; then
        echo 'Behind Cloudflare'
        return
    fi
    IP_ADDR=$(dig +short "$1")
    echo "$IP_ADDR"
    grep -B 2 "$IP_ADDR" ~/.ssh/config | grep 'Host '
}
lorem() {
    WORD_LENGTH=$(((RANDOM % 5) + 5))
    WORD=$(openssl rand -base64 12| head -n 1 | cut -c1-"$WORD_LENGTH")
    SENTENCE="$WORD"
    for i in {1..40}; do
        WORD_LENGTH=$(((RANDOM % 5) + 5))
        WORD=$(openssl rand -base64 12| head -n 1 | cut -c1-"$WORD_LENGTH")
        SENTENCE="$SENTENCE $WORD"
    done
    echo $SENTENCE
}
amis() {
    aws ec2 describe-images --owners self | jq '.Images[] | {id: .ImageId, name: .Name, state: .State, snapshot: .BlockDeviceMappings[0].Ebs.SnapshotId}'
}
rm_ami() {
    AMI_NAME="$1"
    DATA=$(aws ec2 describe-images --owners self)
    AMI_ID=$(echo "$DATA"| jq '.Images[] | select(.Name | contains("'"$AMI_NAME"'")) | .ImageId' |  sed -e 's/^"//' -e 's/"$//')
    SNAPSHOT_ID=$(echo "$DATA"| jq '.Images[] | select(.Name | contains("'"$AMI_NAME"'")) | .BlockDeviceMappings[0].Ebs.SnapshotId' |  sed -e 's/^"//' -e 's/"$//')
    aws ec2 deregister-image --image-id "$AMI_ID"
    aws ec2 delete-snapshot --snapshot-id "$SNAPSHOT_ID"
}
settitle() {
    xdotool set_window --name "$*" $(xdotool getactivewindow)
}
csv() {
    clear; csvlook -d ',' --no-inference "$1" | less -s
}
y() {
    yank | xp
}
gbxm() { # Clear out branches
    git branch | egrep -v "(master)" | xargs -n 1 git branch -D
    rm -rf .git/refs/remotes/origin/*
    git fetch origin master
}
d() { # reset monitors on desktop
    i3-msg "workspace 1, move workspace to output DVI-D-1"
    i3-msg "workspace 2, move workspace to output DVI-I-1"
    i3-msg "workspace 3, move workspace to output HDMI-4"
}
mkv2mp4() { # Create an mp4 of mkv
    ffmpeg -i "$1" -codec copy "${1%.*}.mp4"
}
rzf() {
    local FILENAME=$(fzf)
    local DIRNAME=$(dirname "${FILENAME}")
    ranger "${DIRNAME}"
}

btc() { # Get current btc
    curl -s https://bitpay.com/api/rates | python -c "import json, sys; print(json.load(sys.stdin)[6]['rate'])"
}
btcc() { # convert btc to cad
    BTC_RATE=$(curl -s https://bitpay.com/api/rates | python -c 'import json, sys; print(json.load(sys.stdin)[6]["rate"])')
    echo $(($1 * $BTC_RATE))
}
brightd() {
    sudo python3 "$HOME/.dotfiles/repos/additional/scripts/brightness_daemon.py"
}
brightness_up() {
    echo 'up' | nc -U /tmp/brightd.sock
}
brightness_down() {
    echo 'down' | nc -U /tmp/brightd.sock
}
tlo () {
    if [[ -z "$1" ]]; then
        return
    fi
    local PROJS=($(find "$HOME"/Work/* -mindepth 1 -maxdepth 1 -type d))
    local PROJ_NAME=''
    local PROJ_DIR=''
    for dir in "${PROJS[@]}"; do
        if [[ $(basename "$dir") == "$1" ]]; then
            PROJ_NAME=$(basename "$dir")
            PROJ_DIR="$dir/code"
            tmux new-session -c "${PROJ_DIR}" -s "${PROJ_NAME}"
            return
        fi
    done
    echo "Project '${1}' was not found"
}

gpp() {
    MESSAGE=${1:-auto}
    git commit -m "$MESSAGE" && git push origin master
}
gppa() {
    MESSAGE=${1:-auto}
    git add -A; git commit -m "$MESSAGE" && git push origin master
}
cwh() {
    cat $(which "${1}")
}
vwh() {
    nvim $(which "${1}")
}
xephyr() {
    Xephyr -br -ac -noreset -screen 1080x1080 :1
}
pwgen() {
    date +%s | sha256sum | base64 | head -c 32 | cut -c1-10
}
# rotate uses ImageMagick
rotate() { convert "$1" -rotate 90 "$1" }
rotate90() { convert "$1" -rotate 90 "$1" }
rotate180() { convert "$1" -rotate 180 "$1" }
rotate270() { convert "$1" -rotate 270 "$1" }
# task warrior commands
tkwa() {task add "$1" +work; task sync}
tkpa() {task add "$1" +personal; task sync}
tkw() {task +work}
tkp() {task +personal}
ts() {task sync}
ttotal() {
    task "$1" information | grep 'duration' | awk -F'duration: ' '{ print $2 }' | cut -d')' -f1 | iso8601_adder
}
twstart() {
    TAG=$(cat ~/.timewarrior/my_tags | fzf)
    timew start "$TAG"
}
twstop() {
    TAG=$(cat ~/.timewarrior/my_tags | fzf)
    timew stop "$TAG"
}
twremove() {
    TAGS=(${(f)"$(cat ~/.timewarrior/my_tags | fzf --multi)"})
    for TAG in ${TAGS[@]}; do
        sed -i '/'"$TAG"'/d' ~/.timewarrior/my_tags
    done
}
twsummary() {
    timew summary
}
twsummaryt() {
    TAG=$(cat ~/.timewarrior/my_tags | fzf)
    timew summary "$TAG"
}
inc() {
    nvim ~/.dotfiles/zsh/includes
}
dot2png() {
    dot "${1}" -Tpng -o "${1%.*}.png"
}
dot2svg() {
    dot "${1}" -Tsvg -o "${1%.*}.svg"
}
alias vbm="vboxmanage"
xlsx2csv() {
    in2csv "${1}" > "${1%.*}.csv"
}
xls2csv() {
    in2csv "${1}" > "${1%.*}.csv"
}
klu() {
    CLUSTER=$(kubectl config get-contexts | tail -n +2 |  awk '{ print $2 }' | fzf)
    kubectl config use-context "$CLUSTER"
}
ksl() {
    kubectl get svc
}
kdl() {
    clear
    kubectl get deployment -o wide | less -S
}
kex() {
    POD=$(kubectl get pods | tail -n +2 |  awk '{ print $1 }' | fzf)
    kubectl exec -it "$POD" -- bash
}
klf() {
    POD=$(kubectl get pods | tail -n +2 |  awk '{ print $1 }' | fzf)
    kubectl logs --follow "$POD"
}
mrs() {
    TOKEN=$(sops -d /not/real/path/to/keys.yaml | yq -r .gitlab_token)
    curl --header "PRIVATE-TOKEN: ${TOKEN}" -X GET "https://gitlab.com/api/v4/projects/someproject/merge_requests?state=opened" 2> /dev/null | \
        jq ".[] | {title: .title, branch: .source_branch, author: .author.name, web_url: .web_url, labels: .labels}"
}
mrsc() {
    TOKEN=$(sops -d /not/real/path/to/keys.yaml | yq -r .gitlab_token)
    curl --header "PRIVATE-TOKEN: ${TOKEN}" -X GET "https://gitlab.com/api/v4/projects/someproject/merge_requests?state=merged&order_by=updated_at" 2> /dev/null | \
        jq "limit(4;.[]) | {title: .title, branch: .source_branch, author: .author.name, web_url: .web_url}"
}
glab_ci() {
    TOKEN=$(sops -d /not/real/path/to/keys.yaml | yq -r .gitlab_token)
    RUNNING_BRANCH=$(curl --header "PRIVATE-TOKEN: ${TOKEN}" -X GET "https://gitlab.com/api/v4/projects/someproject/pipelines?status=running" 2> /dev/null | jq -r ".[0].ref")
    glab ci view $RUNNING_BRANCH
}

2faimport() {
    if [[ "$#" -ne 2 ]]; then
        echo 'error in num args'
    else
        # 1 is image 2 is account
        zbarimg -q --raw "${1}" | pass otp append "${2}"
    fi
}
2fadisplay() {
    pass otp uri -q "${1}"
}
rst2md() {
    pandoc -s -o "${1%.*}.md" "${1}"
}
rtf2txt() {
    unoconv -f txt "${1}"
}
zshpure() {
    zsh -d -f -i
}
cheat() {
    curl https://cheat.sh/"${1}"
}
fz() {
    DIR=$(_z 2>&1 -l "${1}" | rg -v 'common:' | awk '{ print $2 }' | fzf --tac)
    cd $DIR
}
alias icat="kitty +kitten icat"
rwh() {
    readlink $(which "${1}")
}
cdrwh() {
    cd $(dirname $(dirname $(rwh "${1}")))
}
cdr() {
    cd $(dirname $(dirname "${1}"))
}
nums() {
    # set IFS to deal with dirs having spaces
    local IFS=$'\n\t'
    for DIR in $(find . -mindepth 1 -maxdepth 1 -type d | sort); do
        local MYDIR=$(basename "${DIR}")
        local NUMFILES=$(find ${MYDIR} -type f | wc -l)
        printf "%6s %s\n" $NUMFILES $MYDIR
    done
}
l() {
    if [ -x "$(command -v exa)" ]; then
        exa "$@"
    else
        ls "$@"
    fi
}
# This goes in an infinite recursion if exa is not installed. lol
ls() {
    if [ -x "$(command -v exa)" ]; then
        exa "$@"
    else
        ls "$@"
    fi
}
ll() {
    l -l
}
l1() {
    l -1
}

clean_nix_generations() {
    sudo nix-env -p /nix/var/nix/profiles/system --delete-generations +5
    sudo nix-collect-garbage
}
ghprl() {
    gh pr list --author @me --json number,title,headRefName,url | jq -r 'map({number,title,headRefName,url}) | (first | keys_unsorted) as $keys | map([to_entries[] | .value]) as $rows | $keys,$rows[] | @csv' | csvlook -d ',' --no-inference | less
    gh pr list --search "is:open is:pr review-requested:@me" --json number,title,headRefName,url | jq -r 'map({number,title,headRefName,url}) | (first | keys_unsorted) as $keys | map([to_entries[] | .value]) as $rows | $keys,$rows[] | @csv' | csvlook -d ',' --no-inference
}
ghpra() {
    gh pr list --search "is:open is:pr author:@me review:approved" --json number,title,headRefName,url | jq -r 'map({number,title,headRefName,url}) | (first | keys_unsorted) as $keys | map([to_entries[] | .value]) as $rows | $keys,$rows[] | @csv' | csvlook -d ',' --no-inference
}
ghpr() {
    local PR=$(gh pr list --author @me --json number,title -q '.[] | "\(.number) \(.title)"' | fzf --prompt "Which PR do you want to check out?" | awk '{ print $1 }')
    export GH_PR=$PR
}
ghprs() {
    gh pr checks $1
    echo ""
    gh pr view $1
}
ghprd() {
    gh pr diff "$1"
}
ghprm() {
    echo "Merge PR: $1?"
    read choice
    case "$choice" in
      y|Y ) gh pr merge --auto --rebase --delete-branch $1;;
      n|N ) return;;
      * ) echo "invalid";;
    esac
}
ghprr() {
    gh pr list -S 'review-requested:@me'
}
ghil() {
    gh issue list -a @me
}
ghprw() {
    while true :; do clear; gh pr checks "$1" ; sleep 7; done
}