#!/usr/bin/env false # for busybox ash, dash, bash, and zsh. unset FANCY; _=: && [ -z $_ ] && FANCY=1 || FANCY=0 # detect zsh and bash if [ "$FANCY" = 0 ]; then . ~/.prep; fi # handle stuff like /etc/profile and $PATH # combine and load everything containing "YES_MYSHELL" in ~/sh/: [ -z "${0##/*}" ] && sh=zsh || sh="${0#-}" # zsh replaces $0, so hardcode it { [ -d "${XDG_CACHE_HOME:="$HOME/.cache"}" ] || mkdir "$XDG_CACHE_HOME"; } && { [ -d "$XDG_CACHE_HOME/shrc" ] || mkdir "$XDG_CACHE_HOME/shrc"; } && cache="$XDG_CACHE_HOME/shrc/$sh-$$" && if [ -s ~/sh/recombine ] && (. ~/sh/recombine) > "$cache"; then #wc -l "$cache" >&2 preload=:; . "$cache"; unset preload fi ! [ -f "$cache" ] || rm "$cache" unset cache # {{{1 utilities have() { if [ -z "$ZSH_VERSION" ]; then which -- "$1"; else whence -p -- "$1"; fi; } 2>/dev/null has() { have "$@"; } >/dev/null if has sudo; then doas() { printf '\033[7m %s \033[m\n' 'warning: you ran sudo when you meant doas!' sudo "$@" } maybesudo() { sudo "$@"; } elif has doas; then sudo() { printf '\033[7m %s \033[m\n' 'warning: you ran doas when you meant sudo!' doas "$@" } maybesudo() { doas "$@"; } else maybesudo() (__maybesudo "$@") fi ADDPATH() { ### @- append a directory to `$PATH` if it isn't already present. [ $# = 1 ] || { printf >&2 'ADDPATH: expected exactly 1 argument, got %s\n' $#; return 64; } [ "$1" = "${1#[A-Z]:\\}" ] || set -- "$(cygpath -u "$1" || printf '%s\n' "$1")" set -- "$(readlink -f "$1")" "$1" if ! [ -d "$1" ]; then if [ -e "$1" ]; then printf 'ADDPATH: not a directory: %s\n' "$1" >&2 else set -- "$2" "$( (true <"$2") 2>&1)" [ -z "$ZSH_VERSION" ] || 2="${2%: *}" printf 'ADDPATH: %s: %s\n' "$1" "${2##*: }" >&2 fi return 1 fi if [ ${#PATH} = 0 ]; then PATH="$1" return 0 fi case ":$PATH:" in (*":$1:"*) :;; (*) PATH="$PATH:$1";; esac } ROPATH() { [ $# = 0 ] || { printf >&2 'ROPATH: expected exactly 0 arguments, got %s\n' $#; return 64; } local segment= previous= newpath= oldpath="$PATH:" while segment="${oldpath%%:*}"; [ "$segment" != "$oldpath" ]; do [ -z "$segment" ] || [ -z "$previous" ] || newpath="$newpath$previous:" [ -z "$segment" ] || previous="$segment" oldpath="${oldpath#*:}" done [ -z "$previous" ] || printf 'rotated %s\n' "$previous" >&2 [ -z "$previous" ] || newpath="$previous:$newpath" export PATH="${newpath%:}" } # {{{1 configurations umask 022 # umask should be reset else pip might make faulty installations. if [ -d "$HOME/opt/local/bin" ]; then printf 'Warning: You have a %s directory\n consider moving it to %s\n' \ '~/opt/local/bin' '~/.local/bin' >&2 ADDPATH "$HOME/opt/local/bin" else ADDPATH "$HOME/.local/bin" fi # clean up problematic, potentially-inherited exports: unset PREFIX CC CPP CXX LD CFLAGS CPPFLAGS CXXFLAGS LDFLAGS unset AR RANLIB RC WINDRES OBJDUMP OBJCOPY unset LD_LIBRARY_PATH unset CDPATH # grief. [ "$DESKTOP_SESSION" != xfce ] || export QT_QPA_PLATFORMTHEME="" # unhide menu bar #[ "$TERM" != vt102 ] || export TERM="xterm" # PuTTY over serial export EA_AUTH="auth" export EA_DIR="t" export EA_DOMAIN="https://eaguru.guru" export EDITOR=vim export ENV="$HOME/.shrc" # for dash and ash export LESS='-QRSci' export PAGER=less export PYTHONIOENCODING=utf-8 # damnit python! export SSH_AUTH_SOCK=0 # more info: https://0x0.st/NUnw export TZ=':/etc/localtime' # more info: https://0x0.st/NUnv # $LANG has been my bane whenever i forget to set it properly, so check it. if [ "$LANG" != "en_US.UTF-8" ] && [ "$LANG" != "en_CA.UTF-8" ]; then if [ -z "$MSYSTEM" ] || [ "$LANG" != "C.UTF-8" ]; then printf 'Warning: LANG is %s\n' "${LANG:-empty!}" >&2 fi fi # simple commands and aliases {{{1 refresh() ### @- invoke `hash -r`. { hash -r; } pl() ### @- print each argument on its own line. { printf '%s\n' "$@"; } ### @ ll - list files verbosely, fancily, ordered, but not recursively. alias ll=; unalias ll # unalias without spitting an error if has lr; then ll() { lr -1lshGG -o tev "$@" | less; } elif has lr.com; then # https://eaguru.guru/t/lr.com ll() { lr.com -1lshGG -o tuev "$@" | less; } else ll() { ls -lAX --group-directories-first --color=force "$@" | less; } fi if ! has busybox && has busybox-static; then busybox() { busybox-static "$@"; } fi gdp() { ### @- invoke `gd` to diff a commit from its parent. the commit defaults to "HEAD". local commit="${1:-HEAD}" [ $# -le 1 ] || { printf '%s: %s\n' gdp "too many arguments" >&2; return 64; } gd "$commit~" "$commit" } gd() ### @- invoke git's diff subcommand with fewer lines of context. { git diff -U2 "$@"; } rgn() ### @- invoke ripgrep without respecting `.gitignore` files. { rg -u "$@"; } ryp() { rg -M99 -g '*.py' "$@"; } curls() ### @- invoke curl with less noise. { curl -sS "$@"; } curLs() { curl -L --no-progress-meter "$@"; } ash() { PS1='$ ' busybox ash "$@"; } cort() { LC_ALL=C sort "$@"; } revend() ### @- reverse the 4-byte endianness of a single file. *this is an in-place operation!* { objcopy -I binary -O binary --reverse-bytes=4 "$@"; } clone() ### @- invoke rsync suitably for creating virtually indistinguishable copies of files. { maybesudo rsync -aHA --info=progress2 --no-i-r "$@"; } aligntabs() ### @- align tab-delimited fields in stdin. { column -t -s$'\t' "$@"; } __crawl() ( unset CDPATH && cd "${HOME:?\$HOME is unset}" || return [ -d .ssh ] || install -m700 -d .ssh || return # TODO: use umask instead? cd .ssh || return if ! [ -s crawl ]; then grab crawl && chmod 0600 crawl || return; fi TERM=xterm-256color exec ssh -F none -i crawl "$@" ) crawla() ### @- play Dungeon Crawl: Stone Soup through ssh on the akrasiac server. { __crawl joshua@crawl.akrasiac.org "$@"; } # password is joshua crawlz() ### @- play Dungeon Crawl: Stone Soup through ssh on the develz server. { __crawl crawl@crawl.develz.org "$@"; } diff() ### @- use git's diff subcommand for general diffing. { git diff --color=auto --no-ext-diff --no-index --no-prefix "$@"; } gc() ### @- columnize text by using git's column subcommand. ### **TODO:** consider renaming because gc(1) already exists. { git column --mode=dense --padding=2 "$@"; } counts() ### @- count files in the current directory, including files found recursively. { find . | wc -l "$@"; } exts() ### @- count and sort file extensions in the current directory, including files found recursively. { find -type f | sed -e 's@.*/@@' -e 's@.*\.@@' | tr A-Z a-z | scount; } # TODO: don't use GNU options when busybox is detected! nocom() ### @- strip single-line C-like and shell-like comments. { grep -Ev --line-buffered --color=never "^[[:space:]]*(//|#)" "$@"; } jrep() ### @- extract strings comprised of basic ASCII or Japanese codepoints. { grep -aPo '[\x{20}-\x{7E}\x{4E00}-\x{9FFF}\x{3040}-\x{30FF}]+' "$@"; } bomb() ### @- add a Byte-Order Mark to a file. { uconv -f utf-8 -t utf-8 --add-signature "$@"; } cleanse() ### @- strip unprintable and non-ASCII characters. { tr -cd '\11\12\15\40-\176' "$@"; } double() ### @- print every line twice.
print every line twice. ### **NOTE:** there also exists a double(1) program provided by ### the *plotutils* package that i don't use. { awk "{print;print}" "$@"; } katagana() ### @- convert katakana codepoints to their equivalent hiragana. ### this is occasionally useful when translating [debug text from ancient games.](https://tcrf.net/) { perlu -MUnicode::Normalize -pe\''$_=NFKD($_)=~y/ァ-ヶ /ぁ-ゖ /r''\' "$@"; } makepkgf() ### @- make the freakin' package! { makepkg -Af --skipchecksums --skippgpcheck "$@"; } rakef() ### @- make the freakin' gem! { rake && gem build *.gemspec && gem install *.gem "$@"; } relog() ### @- log on again to refresh your unix groups, etc. { exec su - "${USER:?}"; } carry() ### @- copy files in a plain way using rsync. affected by umask. { rsync -HOlrt --no-p --no-g --chmod=ugo=rwX "$@"; } alias 0x0.st="oxo" alias oshi.at="oshi" alias pastel='pastel -f' # why would i want to use a color utility without colors? alias poo="pueue" alias rg="rg -M200" # enable colors {{{2 if [ "$FANCY" = 1 ]; then # busybox is smart enough to ignore --color flags when unsupported. alias grep='grep --color=auto' alias ls='ls --color=auto' alias lr="lr -G" #alias make="$(have colormake || have make)" fi