#!/bin/zsh

#################################################################################
# daily use aliases
##############################################################################{{{

alias ls="ls --group-directories-first -N --color=auto"
alias ll="ls -hl"
alias lll="ls -hla"
alias ds="du -sh"
alias :q="exit"

alias rget="rsync -rP --append-verify --inplace"
alias 7zu="7z a -t7z -m0=lzma -mx=9 -mfb=64 -md=32m -ms=on"

alias cronmail="mutt -f $MAIL -F <(grep -v 'set folder' ~/.config/mutt/neomuttrc | grep -v 'mailboxes'; echo 'mailboxes $MAIL\nset folder=$MAIL')"

alias d="dragon-drop -a -x -T"

if ! command -v fd >/dev/null; then
    if command -v fdfind >/dev/null; then
	alias fd="fdfind"
	autoload -Uz _fd
	compdef _fd fdfind
    else
	fd() {
	    if [[ "$1" =~ "^-" ]]; then
		echo "fd not installed. shell alias supports only basic operation"
		return 1
	    fi
	    noglob find . -iname "*${*}*"
	}
    fi
fi

alias sudo="sudo "
alias S='sudo $(history -n -1)'

alias rm="rm -I"
if exists rifle; then
    alias v=rifle
else
    function v() {
	for file in $@; do
	    xdg-open $file &|
	done
    }
fi

alias vmemcache="vmtouch -l -m 12G -v"


fork() {
	"$@" &>/dev/null &|
}

alias en="pipx run dict.cc.py de en"
alias de="pipx run dict.cc.py en de"

su() {
    if [[ -z "$@" ]]; then
	echo "Switching to sudo -i for enviromental reasons"
	sudo -i
    else
	command su "$@"
    fi
}

loadgroup() {
    if [[ -z $1 ]]; then
	echo "Usage: loadgroup <new group name>"
	return 1
    fi
    exec sg $1 newgrp $(id -gn)
}

#}}}

#################################################################################
# zsh stuff
##############################################################################{{{

alias histoff="HISTFILE=/dev/null"
alias histon="HISTFILE=$HOME/.histfile"
E() {
    if [[ -n $(jobs) ]]; then
	echo "exec: You have suspended jobs."
    else
	builtin exec zsh
    fi
}


# edit and refresh aliases
aliases() {
    $EDITOR $(zdotfile aliases/${1:-functions})
    source $(zdotfile aliases)/*
}

# per directory configuration
cd(){
    if [ -e ".zout" ]; then
        . "./.zout"
    fi
    builtin cd $*
    if [ -e ".zin" ]; then
        . "./.zin"
    fi
}

#}}}

#################################################################################
# filesystem stuff
##############################################################################{{{


# count files in current or given directory
count() {
	find $1 -mindepth 1 \( ! -path '*/.*' \) | wc -l
}

pumount() {
	params=()
	while [[ "${1[1]}" == "-" ]]; do
		params+="$1"
		shift
	done
	if [[ "${1[1]}" == "/" ]]; then
		command pumount "${params[@]}" "$1"
	else
		command pumount "${params[@]}" "/media/$1"
	fi
}

dl-source() {
    for file in "$@"; do
	getfattr --only-values -n user.xdg.origin.url "$file" 2>/dev/null && echo || echo "$file: no download source info" >&2
    done
}

receive-subvolume() { nc -c -l -p $2 | btrfs receive -ve $1 }
send-subvolume() { btrfs property set $1 ro true; btrfs send -v $1 | pv | nc -c nashorn.fritz.box $2 }

#}}}

#################################################################################
# filename manipulation
##############################################################################{{{

# prefix all given files with first argument to this function
prefix() {
	pre=$1;shift
	for i in $*; do mv $i $pre$i;done
}

# prefix all given files with consecutive numbers, starting with 1
# or with number given by -s switch (must be first argument)
prenumbering() {
	if [[ "$1" == "-s" ]]; then
		n=${2};
		shift 2
	else
		n=1
	fi
	for i in "$@"; do
		mv $i ${(l:2::0:)n}_$i;
		((n++));
	done
}

# appends given suffix (first argument)
suffix() {
	suf=$1;shift
	for i in $*; do mv $i $i$suf;done
}

#}}}

#################################################################################
# audio video photo
##############################################################################{{{

alias exifcopy="exiftool -tagsFromFile"
photobydate() {
    local imagefiles
    imagefiles=( ${*:-(#i)*.(JPG|CR[23]|DNG)(N)} )
    for i in ${imagefiles[@]}; do
	if [[ -e $i ]]; then
	    dir=$(exiftool -p '$DateTimeOriginal' $i 2>/dev/null | tr ':' '-' | cut -d' ' -f1;)
	    mkdir -p $dir
	    printf "%s\n" ${i:r}.*
	    mv ${i:r}.* $dir
	fi
    done | tqdm --total $#imagefiles --unit=imgs >> /dev/null
}

alias mkvidentify="mkvmerge --identify"

cropdetect() {
	ffmpeg -ss ${2:-00:05:00} -t 1 -i "${1}" -vf cropdetect -f null - 2>&1 | awk '/crop/ { print $NF }' | tail -1
}
#}}}

#################################################################################
# programming
##############################################################################{{{

if [[ -n $PAGER ]]; then
    svn() {
	    case $1 in
		    log|diff)
			    command svn "$@" | $PAGER ;;
		    *)
			    command svn "$@" ;;
	    esac
    }
fi

alias gitv='vim "$(git rev-parse --git-dir)/index" -c "Gitv --all" -c tabonly'

#}}}

#################################################################################
# noglobs
##############################################################################{{{
alias ri=noglob\ ri
alias wcalc="noglob wcalc"
#}}}

#################################################################################
# tmux
##############################################################################{{{

tdetachprep() {
	env -i tmux new-session -d -s detached &>/dev/null
}

alias :u="tmux select-pane -U"
alias :d="tmux select-pane -D"
alias :l="tmux select-pane -L"
alias :r="tmux select-pane -R"
alias :split="tmux splitw -v"
alias :vsplit="tmux splitw -h"
alias :detachw="tdetachprep; tmux movew -t detached: -s"
alias :attachw="tdetachprep; tmux movew -t : -s"

#}}}

#################################################################################
# btrfs
##############################################################################{{{

btrfs-subvolume-force-delete() {
	btrfs property set "$1" ro false
	btrfs subvolume delete "$1"
}

#}}}
#
#################################################################################
# global and suffix aliases
##############################################################################{{{

# lazy shortcuts
alias -g G="| grep"
alias -g L="| ${PAGER:-less}"
alias -g LE="2>&1 | ${PAGER:-less}"
alias -g T="| tail"

# xclipboard
alias -g XS='$(xclip -o -selection primary)'
alias -g XC='$(xclip -o -selection clipboard)'

alias -g GITROOT='$(git rev-parse --show-toplevel)'

alias -s log=vimpager
#}}}

#################################################################################
# various small scripts
##############################################################################{{{

alias urldecode="python3 -c 'import sys; from urllib import parse; print(parse.unquote_plus(sys.stdin.read().strip()))'"
alias urlencode="python3 -c 'import sys; from urllib import parse; print(parse.quote_plus(sys.stdin.read().strip()))'"

#}}}

eth-ip() {
	ip a show primary dev ${1:-/sys/class/net/en*~*/lo(:t)} | awk '/\s*inet / { split($2,a,"/");print a[1] }'
}

fasel-tunnel() {
	if [[ -z "$1" || -z "$2" || "$1" == "-h" || "$1" == "--help" ]]; then
		echo "Usage: fasel-tunnel <host> <port> [remote_port]"
		return
	fi
	local host="$1";
	local port="$2";
	local remote_port="${3:-$2}"
	ssh -L $port:$host:$remote_port fasel -N &
}

tmpssh() {
	dir=/tmp/${${1#*:}:t}
	mkdir -p ${dir}
	sshfs $1 ${dir}
	cd ${dir}
}

alias jdl="docopen $HOME/.jails/*/Downloads"
alias vcat="nvimpager -c"

alias luarocks="luarocks --local"

alias icat="kitty +kitten icat"

local function hour-float-to-time() {
    printf "%d:%02dh" $1 $(( $1 * 60 % 60 ))
}

batstat() {
    for bat in /sys/class/power_supply/BAT*; do
	local energy_full=$(<$bat/energy_full)
	local energy_now=$(<$bat/energy_now)
	local power_now=$(<$bat/power_now)
	local bat_status=$(<$bat/status)
	local remain_text
	local remain
	case $bat_status in
	    Charging)
		remain=$(((energy_full - energy_now) / power_now))
		remain_text=", $(hour-float-to-time $remain) until full"
		;;
	    Discharging)
		remain=$((energy_now / power_now))
		remain_text=", $(hour-float-to-time $remain) left"
		;;
	    *)
		remain_text=""
		;;
	esac

	printf "%s: %.1f %%, %s%s\n" \
	    ${bat:t} \
	    $(( energy_now * 100.0 / energy_full )) \
	    $bat_status \
	    $remain_text
    done
}

if [[ $DISPLAY ]] && exists xinput && exists xrandr && \
xinput | grep -q Wacom && xrandr | grep -q eDP1; then
    xrandr() {
	command xrandr $@
	for dev in $(xinput | grep Wacom | grep -oP '(?<=id=)\d*'); do
	    xinput map-to-output $dev eDP1
	done
    }
fi

function lastdl() {
    echo ~/downloads/*(oc.[1])
}

alias mpvu="noglob mpv"

# copilot
function gh-copilot-cli() {
    local tpe="$1"; shift
    gh copilot suggest -t $tpe "$*"
}

alias C="gh-copilot-cli shell"
alias Cgit="gh-copilot-cli git"
alias Cgh="gh-copilot-cli gh"

alias e="nvim -c 'lua require(\"telescope.builtin\").fd { cwd = require(\"findroot\")(require(\"telescope.utils\").buffer_dir()) } '"

if [[ -e ${XDG_CONFIG_HOME}/broot/launcher/bash/br ]]; then
	source ${XDG_CONFIG_HOME}/broot/launcher/bash/br
fi

duplicates() {
    sort | uniq -c | grep -v '^\s*1'
}

alias rg="RIPGREP_CONFIG_PATH=$XDG_CONFIG_HOME/ripgreprc rg"

if exists gron; then
    jgrep() {
	gron | grep "$@" | gron -u
    }
fi
