########################### #### Function Definitions # ########################### ## Selfupdate function dotfiles_selfupdate { (DOTFILES_FORCEUPDATE=1 source $DOTFILES/extras/check_for_update.zsh || echo "[dotfiles_selfupdate] failed") } ## get cheat sheets for commands from cheat.sh. Usage: cheat commandname function cheat { curl "https://cheat.sh/$1" } # get cheat sheets for commands matching $1 function cheatall { curl "https://cheat.sh/~$1" } # List all docker tags for an image function dockertags { if [[ -z $(command -v jq) ]]; then echo "jq not installed. Please install jq." 1>&2 return fi i=0 while [[ $? == 0 ]]; do i=$(($i+1)) curl "https://registry.hub.docker.com/v2/repositories/library/$1/tags/?page=$i" 2>/dev/null | jq '."results"[]["name"]' done } # watch with grc enabled function watchgrc { watch -n 1 -c grc --colour=on "$@" } ## Simple calculator. Usage: calc 1+1, calc 5/7, calc "sqrt(2)" function calc { awk "BEGIN { print $* }" } function warning { echo -e "${Yellow}Warning:$CLEAR $@" >&2 } function error { echo -e "${Red}Error:$CLEAR $@" >&2 } function info { echo -e "${Green}Info:$CLEAR $@" } ## Flashes the screen until user presses a key function flasher { while true; do printf "\e[?5h\007"; sleep 0.25; printf "\e[?5l"; read -s -n -t1 && break; done; } ## Beep until user presses a key function beeper { while true; do printf "\e[?5h\007"; sleep 0.25; printf "\e[?5l"; read -s -n -t1 && break; done; } # set an alarm in seconds, minutes, hours function alarm { if [[ -z $1 ]]; then echo "Usage: alarm 5[s]|5m|1h" return 1 fi value=$1 local t if [[ $value = *"m" ]]; then t=$((${value/m/}*60)) elif [[ $value = *"h" ]]; then t=$((${value/h/}*3600)) elif [[ $value = *"s" ]]; then t=${value/s/} else t=$value fi function format(){ if [[ $1 -lt 60 ]]; then printf "00:%02is" $1 return fi if [[ $1 -lt 3600 ]]; then minutes=$(($1/60)) seconds=$(($1%60)) printf "%dm:%02dm" $minutes $seconds return fi hours=$(($1/3600)) remainder=$(($1%3600)) printf "%dh:%s" hours "$(format $remainder)" } count=$t while [[ $count -ge 0 ]]; do echo -en "Set a timer for $1 │ remaining=$(format $count)" count=$((count-1)) sleep 1 echo -en "\r" done echo -e "\nDone!" beeper } ## Simple http server for current directory (or path) function httpserver { ( if [[ -d $1 ]]; then cd "$1" && echo "Starting webserver in $(realpath $1)/" || echo "directory: $1 does not exist" >&2 || exit 1 else echo "Starting webserver in $PWD/" fi open "http://localhost:8000" &>/dev/null & python -m http.server 8000 ) } alias webserver='httpserver' ## Upload something using the 0x0.st service. Usage: upload [filename|url] function upload { local url if echo "$@" | grep -E -s -q "^http[s]://"; then url=true fi if [[ $url == true ]]; then out="$(curl -F"url=$@" https://0x0.st)" else out=$(curl --progress-bar -F"file=@$@" "https://0x0.st/") fi if [[ $? -ne 0 ]]; then echo -e "Failed uploading $@:\n $out" >&2 return fi echo -e "Done, file at:\t$out" if [[ $(uname) == "Darwin" ]]; then clipboard="pbcopy" elif command -v wl-copy &>/dev/null; then clipboard="wl-copy" elif command -v xclip &>/dev/null ; then clipboard="xclip" else clipboard="cat" fi echo -en "$out" | $clipboard } ## If connecting through ssh and reverse forwarding port 2222 (ssh -R 2222:localhost:22 ), this function allows to copy the files back to the machine one is connecting from by typing 'mecp filename' (configure the username for "localhost" in ~/.ssh/config or add an username) function mecp { rsync -r -P -e "ssh -p 2222" -R "$@" localhost:~/Desktop/ } ## generate a password using pwgen, generate_password 20 generates a 20 characters long password function generate_password { pwgen -1sycn $1 } ## Generate a password from dev urandom using only printable characters function genpwd { if [[ $1 ]]; then strlen=$1 else strlen=32 fi # All characters excluding backlash env LC_CTYPE=C tr -dc '[:graph]\' < /dev/urandom | fold -w $strlen | head -n 1 } ## List defined functions in $DOTFILES/functions.sh function list_functions { grep --color=no -A 1 '^##' $DOTFILES/functions/*.zsh| sed -E 's/function (.*)/\1/g' } # MacOS only if [[ "$(uname)" == "Darwin" ]]; then ## Create a RAM disk. Default size 1GB. If supplied, first argument defines the RAM disk size in GB function ramdisk { if [[ -e $1 ]]; then sizeingb=$1 else sizeingb=1 fi # Numsectors is size in bytes / 512 (sector size in bytes) name='RAM_disk' sizeinbytes=$(($sizeingb*1000**3)) NUMSECTORS=$(($sizeinbytes/512)) mydev=$(hdiutil attach -nomount ram://$NUMSECTORS ) # strip whitespace (hdiutil outputs a lot of spaces/tabs along with the device name) mydev=$(echo "$mydev"| xargs echo) newfs_hfs "$mydev" mkdir -p "/tmp/$name" mount -t hfs "$mydev" "/tmp/$name" echo "RAM Disk mounted: /tmp/$name" echo "To eject (destroy) RAM disk, use:" echo " $ diskutil eject $mydev" } fi # unzip file to directory with the same name of the zip file (without extension) function unzipd { zip_file="$1" filename=$(basename -- "$zip_file") extension="${filename##*.}" name="${filename%.*}" unzip -d "$name" "$zip_file" } fvim() { if [[ -n "$@" ]]; then vim `fzf -q $@` else vim `fzf` fi } # retry command until it succeeds (waiting one second or $RETRY_INTERVAL) function retry() { until $@; do sleep ${RETRY_INTERVAL:-1}; done } __completion_wrapper(){ # Wrapper for completion functions. # These can be used to force loading of all completions # for the given command in order to access specialized # completion functions local _completion_function=$1 local _completion_base=$2 if ! command -v $_completion_function &>/dev/null; then $_completion_base fi $_completion_function } if command -v pacman &>/dev/null ; then pacbins() { pacman -Ql $1 | sed -n -e 's/.*\/bin\///p' | tail -n +2 } _pacbins(){ # fix completion __completion_wrapper _pacman_completions_installed_packages _pacman } compdef _pacbins pacbins fi if command -v rustc &>/dev/null then rexplain() { rustc --explain $@ | bat --language=rust - } fi if command -v fzf &>/dev/null ; then falias() { alias | fzf $@ | cut -d= -f 1 } fi make_backup() { name="$1" backup_name="backup_$1_$(date +%Y-%m-%d).tar.gz" echo "Backing up to $backup_name" tar -czf "$backup_name" "$1" echo "done" } function find_by_mtime() { find $@ -printf "%T+ %p\n" | sort } function mangrep() { if [[ -z "$@" ]]; then echo "Usage: $0 " echo "Opens man page for at the first match for " return fi pattern=$1 cmd=$2 if [[ -z "$cmd" ]]; then man "$cmd" return fi MANPAGER="less -p \"$pattern\"" man "$cmd" } # watches the given file/directory and executes the given action whenever anything is changed. Usage: watch_and_run function watch_and_run() { if ! which inotifywait 2>&1 &>/dev/null ; then echo "$0 requires inotifywait"; return 1; fi [[ -z "$1" ]] && echo "Usage: $0 " && return 1 local to_watch=$1 shift [[ -z "$@" ]] && echo "Usage: $0 " && return 1 local action="$@" local _bg_job_pid local TRAPINT(){ if [[ -n ${_bg_job_pid} ]]; then kill -9 ${_bg_job_pid} fi yellow '\nQuitting.' break; } { set +m # disable job control messages while true; do if [[ ! -e "$to_watch" ]]; then echo "\"$to_watch\" does not exist"; break fi zsh -c "$action" & _bg_job_pid=$! disown echo -e "$Cyan ==> Running \"$action\" with pid=${_bg_job_pid}$CLEAR" # block until the file/directory has been written to inotifywait -e close_write -r "$to_watch" &>/dev/null # the job might have failed, ignore errors kill -9 ${_bg_job_pid} &>/dev/null || true done } always { # remove ctrl-c trap unset -f TRAPINT set -m # restore job control messages } } # use watch and force color with grc function watchc() { watch --differences --interval 1 --color grc --colour=on $@ } # make a backup copy of the argument adding the .bak suffix function bak() { cp $1{,.bak} } # restore a backup copy created using `bak` function unbak() { mv $1{.bak,} } # highlight functions with when calling which function which(){ if ! (($+commands[bat])); then builtin which $@ else builtin which $@ | bat --language=zsh fi }