# Jonathan Frech, 2021-09-28, 2021-09-29, 2021-10-06, 2021-10-10, 2021-10-31, 2022-05-20, 2022-06-04
# .bashrc

GIT_DIRECTORY="$HOME/git"
GIT_IDEA_REPOSITORY="$GIT_DIRECTORY/strom/aa_active"



# TODO temporarily written here
setup-environment () {
    # [2022-06-04] see https://github.com/b3nj5m1n/xdg-ninja/tree/main/programs
    # [2022-06-04] see https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
    export XDG_DATA_HOME="$HOME/.local/share"
    export XDG_CONFIG_HOME="$HOME/.config" # TODO Why is this not already set?
    #export XDG_STATE_HOME="$HOME/.local/state"
    # XDG_RUNTIME_DIR
    mkdir -p "$XDG_CONFIG_HOME" "$XDG_DATA_HOME"

    banish-histories

    export EDITOR='vim'
    export GOPROXY='direct'
    export INPUTRC="$XDG_CONFIG_HOME"/readline/inputrc
    export GOPATH="$XDG_DATA_HOME"/go

    export GTK2_RC_FILES="$XDG_CONFIG_HOME"/gtk-2.0/gtkrc
    export KDEHOME="$XDG_CONFIG_HOME"/kde
    export GNUPGHOME="$XDG_DATA_HOME"/gnupg
    rm -rf "$HOME/.ivy2"

    export PATH="$PATH:/usr/local/go/bin"
}
banish-histories () {
    export HISTFILE=/dev/null
    export HISTFILESIZE=0
    #export HISTIGNORE='*'
    export HISTSIZE=1024
    rm -f "$HOME/.bash_history"

    export LESSHISTFILE=/dev/null
    export LESSHISTSIZE=0
    rm -f "$HOME/.lesshst"
}


# INTERNAL #####################################################################
################################################################################

# update the `.bashrc` from itself
u () { curl -fsSL https://software.jfrech.com/bash/rc -o "$HOME/.bashrc"; source "$HOME/.bashrc"; }

error () { IFS=' '; printf ''; printf '\33[1m\33[91merror\33[m: %s\n' "$*"; return 1; }

decode-base64 () {
    case "$(uname)" in
    FreeBSD) base64 -d ;;
    *) base64 -d - ;;
    esac
}

softly-write-file () {
    b64data="$1"; target="$2"
    printf '%s' "$b64data" | decode-base64 | cmp "$target" 2>/dev/null && return 0
    [ -e "$target" ] && printf 'softly-write-file: target exists with differing content: %s\n' "$target" && return 1
    printf '%s' "$b64data" | decode-base64 > "$target"
}

runc () {
    # run C

    root="/tmp/runc" ; mkdir -p "$root"
    temp="$root/$(uuidgen).temp"

    hash="$(tee "$temp" | sha512sum | cut -d' ' -f1)"
    source="$root/$hash.c" ; binary="$root/$hash"
    mv "$temp" "$source"

    [ ! -f "$binary" ] \
        && ! gcc -Wall -Wpedantic -Wextra -Werror -O3 "$source" -o "$binary" \
        && return 1

    "$binary"
}

b64runc () { printf '%s' "$1" | decode-base64 | runc; }


# UTILITIES ####################################################################
################################################################################

x () {
    # start the Xorg server

    rm -f "$HOME/.Xauthority"
    cd "$HOME" ; XAUTHORITY="$XDG_RUNTIME_DIR/Xauthority" startx "$XDG_CONFIG_HOME/X11/xinitrc"
}

cdr () {
    # "cdr": "CD to Realpath"

    [ $# -ge 2 ] && { error 'too many arguments (expected none or one)'; return 1; }

    o="$PWD"
    case "$1" in
    /*) o='/' ;;
    esac

    n="$(realpath "$o")"
    [ -n "$1" ] && n="$(realpath "$n/$1")"

    [ "$PWD" = "$n" ] && printf '%s (no change)\n' "$n" && return
    printf '%s -> %s\n' "$PWD" "$n"
    cd "$n"
}

ansiclr () { b64runc 'LyogSm9uYXRoYW4gRnJlY2gsIDIwdGggb2YgQXByaWwgMjAyMCAqLwoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGJvb2wuaD4KCiNkZWZpbmUgQ09MT1JfQkxPQ0soTkFNRUxFU1MsIEMsIFQsIEYsIFApIFwKICAgIGlmIChOQU1FTEVTUykgXAogICAgICAgIHByaW50ZigiXDMzWzQ4OzU7JWRtIiBUICJcMzNbMG0iIFAsIEMpOyBcCiAgICBlbHNlIFwKICAgICAgICBwcmludGYoIlwzM1s0ODs1OyVkbSIgRiAiXDMzWzBtIiBQLCBDLCBDKTsKCnZvaWQgYW5zaShib29sIG5hbWVsZXNzKSB7CiAgICBwcmludGYoIlxuIik7CiAgICBmb3IgKGludCB5ID0gMDsgeSA8IDQ7IHkrKykgewogICAgICAgIHByaW50ZigiICAiKTsKICAgICAgICBmb3IgKGludCB4ID0gMDsgeCA8IDg7IHgrKykgewogICAgICAgICAgICBpbnQgYyA9IHggKzgqICEhKHkvMik7CiAgICAgICAgICAgIHByaW50ZigiXDMzWzFtIik7CiAgICAgICAgICAgIHByaW50Zih5IC8gMiA/ICJcMzNbMzg7NTswbSIgOiAiXDMzWzM4OzU7MTVtIik7CiAgICAgICAgICAgIENPTE9SX0JMT0NLKHkgJSAyIHx8IG5hbWVsZXNzLCBjLAogICAgICAgICAgICAgICAgIiAgICAgICAgICAgICIsICIgICAgICUyZCAgICAgIiwgIiAgICAgICAiKTsgfQogICAgICAgIHByaW50ZigiXG4iKTsgfQogICAgcHJpbnRmKCJcbiIpOwoKICAgIGZvciAoaW50IHIgPSAwOyByIDwgNjsgcisrKQogICAgICAgIGZvciAoaW50IHkgPSAwOyB5IDwgMjsgeSsrKSB7CiAgICAgICAgICAgIGZvciAoaW50IGcgPSAwOyBnIDwgNjsgZysrKQogICAgICAgICAgICAgICAgZm9yIChpbnQgYiA9IDA7IGIgPCA2OyBiKyspIHsKICAgICAgICAgICAgICAgICAgICBpbnQgYyA9IDE2ICsgcio2KjYgKyBnKjYgKyBiOwogICAgICAgICAgICAgICAgICAgIHByaW50ZigiXDMzWzFtIik7CiAgICAgICAgICAgICAgICAgICAgcHJpbnRmKGcgPCAzID8gIlwzM1szODs1OzE1bSIgOiAiXDMzWzM4OzU7MG0iKTsKICAgICAgICAgICAgICAgICAgICBDT0xPUl9CTE9DSyh5IHx8IG5hbWVsZXNzLCBjLCAiICAgICIsICIlNGQiLCAiIik7CiAgICAgICAgICAgICAgICAgICAgaWYgKCEoKGIrMSkgJSA2KSkKICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRmKCIgIik7IH0KICAgICAgICAgICAgcHJpbnRmKCJcbiIpOyB9CiAgICBwcmludGYoIlxuIik7CgogICAgZm9yIChpbnQgeSA9IDA7IHkgPCAyOyB5KyspIHsKICAgICAgICBwcmludGYoIiAgICAiKTsKICAgICAgICBmb3IgKGludCBrID0gMDsgayA8IDI0OyBrKyspIHsKICAgICAgICAgICAgcHJpbnRmKCJcMzNbMW0iKTsKICAgICAgICAgICAgcHJpbnRmKGsgPCAxMiA/ICJcMzNbMzg7NTsxNW0iIDogIlwzM1szODs1OzBtIik7CiAgICAgICAgICAgIGludCBjID0gMTYgKyAyMTYgKyBrOwogICAgICAgICAgICBDT0xPUl9CTE9DSyh5IHx8IG5hbWVsZXNzLCBjLCAiICAgICIsICIlNGQiLCAiICAiKTsgfQogICAgICAgIHByaW50ZigiXG4iKTsgfQogICAgcHJpbnRmKCJcbiIpOyB9CgppbnQgbWFpbigpIHsKICAgIGFuc2koZmFsc2UpOwogICAgYW5zaSh0cnVlKTsgfQo='; }


# CONFIG BUILDERS ##############################################################
################################################################################

setup-vimrc () {
    b64data_vimrc='IiBKb25hdGhhbiBGcmVjaCdzIHZpbSBydW4gY29tbWFuZDsgbGFzdCBtb2RpZmllZCAyMDIxLTA5LTA0LCAyMDIxLTEwLTExLCAyMDIyLTA1LTI2CgoiIiIgcmVmZXJlbmNlcwoiICogW05laWwxNV0gRHJldyBOZWlsLiAqUHJhY3RpY2FsIFZpbSA7IEVkaXQgVGV4dCBhdCB0aGUgU3BlZWQgb2YgVGhvdWdodCoKIiAgICAgICAgICAgICgybmQgZWQuKS4gUmFsZWlnaCwgTm9ydGggQ2Fyb2xpbmE6IFRoZSBQcmFnbWF0aWMgQm9va3NoZWxmLCAyMDE1LgoiICAgICAgICAgICAgSVNCTi0xMzogOTc4LTEtNjgwNTAtMTI3LTgKCiIiIiBmYWN0cwoiICogW05laWwxNSwgcC4geHh2XTogYCQgdmltIC11IE5PTkUgLU5gIGludm9rZXMgYSBjbGVhbiB2aW0gKGN1cnJlbnQgc3lzdGVtJ3MgZGVmYXVsdHMpCgoiIiIgcGxhbnMKIiAqIExlYWRlciBzaG9ydGN1dHMgZm9yIGBicHJldmAsIGBibmV4dGAsIGBiZmlyc3RgIGFuZCBgYmxhc3RgPyAocmVmLiBbTmVpbDE1LCBwLiA4NV0pCiIgKiBVc2UgYDpmaW5kYCBtb3JlIG9mdGVuLgoiICogQ2hlY2sgb3V0IGBodHRwczovL3d3dy52aW1nb2xmLmNvbS9gIChyZWYuIFtOZWlsMTUsIHAuIDE4XSkuCiIgKiBDaGVjayBvdXQgYGh0dHA6Ly92aW1jYXN0cy5vcmcvYCAocmVmLiBbTmVpbDE1LCBwLiA0NF0pLgoiICogQ29uc2lkZXIgYWRkaW5nIFtOZWlsMTUsIHAuIDEwMV0ncyBgJSVgIHN5bWJvbCBzdWdnZXN0aW9uLgoiICogRmlndXJlIG91dCBob3cgdG8gY29uZmlndXJlIGBwYXRoYCBhbmQgYHdpbGRtb2RlYCB0byBteSBsaWtpbmcgKHJlZi4gW05laWwxNSwgcHAuIDEwMi0tMTAzKS4KCgoiIFtOZWlsMTUsIHAuIDEwNF0Kc2V0IG5vY29tcGF0aWJsZQpmaWxldHlwZSBwbHVnaW4gb2ZmICIgWFhYIG9uCgpzZXQgbnJmb3JtYXRzLT1vY3RhbCAiIFtOZWlsMTUsIHAuMjJdCgoKIiBmb3JjZSBVVEYtOApzZXRnbG9iYWwgZmlsZWVuY29kaW5nPXV0Zi04CnNldGdsb2JhbCBmaWxlZW5jb2RpbmdzPXV0Zi04CnNldGdsb2JhbCBlbmNvZGluZz11dGYtOAoKIiBbTmVpbDE1LCBwLiA5NF06IGhlIHVzZXMgdGhlIG1vdXNlIGZvciB3aW5kb3cgcmVzaXppbmcKIiBJIGRldGVzdCB0aGUgbW91c2UKc2V0IG1vdXNlPQoKIiBJIHRoaW5rIHRoaXMgYWxsb3dzIHZpbSB0byBtYWtlIHVzZSBvZiBYLWluZHVjZWQgc3BlY2lhbCBwYXN0aW5nIGVzY2FwZQoiIHNlcXVlbmNlcyAoaW4gd2hpY2ggdGhlIHBhc3RlZCB0ZXh0IGlzIHdyYXBwZWQpLgpzZXQgcGFzdGUKCiIgc2V0IHNwYWNlIGJhciBhcyBhIGxlYWRlcgpsZXQgbWFwbGVhZGVyID0gIiAiCgoiIGRvIG5vdCBtZXNzIHdpdGggZWRpdGluZwpzZXQgZm9ybWF0b3B0aW9ucz0KIiB1c2UgZm91ciBzcGFjZXMgaW5zdGVhZCBvZiBhIHRhYgpzZXQgZXhwYW5kdGFiIHNvZnR0YWJzdG9wPTQgc2hpZnR3aWR0aD00ICIgW05laWwxNSwgcC4gNDRdCnNldCBub3NoaWZ0cm91bmQgIiBUT0RPIGRvZXMgbm90IGFwcGVhciB0byB0YWtlIGVmZmVjdApzZXQgdGFic3RvcD00ICIgW05laWwxNSwgcC4gMzZdCnNldCBub2NpbmRlbnQgbm9zbWFydGluZGVudCBpbmRlbnRleHByPQpzZXQgdGV4dHdpZHRoPTAgbm9hdXRvaW5kZW50ICIgW05laWwxNSwgcC4gMzNdCgoKIiBhbGxvdyBmb3IgYSBtb3JlIGZsZXhpYmxlIGluc2VydCBtb2RlCnNldCBiYWNrc3BhY2U9aW5kZW50LGVvbCxzdGFydAoKIiBNYWtlIGBZYCBub3Qgd29yayBhcyBgeXlgIGJ1dCBpbnN0ZWFkIGFzICd5YW5rIHRvIGVuZCBvZiBsaW5lJy4Kbm9yZW1hcCBZIHkkCgoKCiJUT0RPICIgdGhlIGRpcmVjdG9yeSAiJEhPTUUvLnZpbSIgc2hvdWxkIGhhdmUgYmVlbiBjcmVhdGVkCiJUT0RPIHNldCBoaWRkZW4gdW5kb2ZpbGUgdW5kb2Rpcj0kSE9NRS8udmltL3VuZG8KCnNldCBwYXRoKz0qKiAiIHNlZSBhbHNvIFtOZWlsMTUsIHAuIDEwMl0Kc2V0IGhpZGRlbiAiIFtOZWlsMTUsIHAuIDkxXQoKCiIgYnkgZGVmYXVsdCwgc3BsaXRzIHNoYWxsIG9wZW4gYWJvdmUgYW5kIHRvIHRoZSBsZWZ0CnNldCBzcGxpdGJlbG93IHNwbGl0cmlnaHQKCiIgY29uZmlndXJlIGluZm8gc2hvd24Kc2V0IHNob3dtb2RlIHNob3djbWQKc2V0IG5vc2hvd21hdGNoIG1hdGNocGFpcnMrPTw6PgpzZXQgaWdub3JlY2FzZSBzbWFydGNhc2UgaW5jc2VhcmNoCnNldCBzY3JvbGxvZmY9NQpzZXQgbm9zaG9ydG5hbWUKc2V0IHNob3d0YWJsaW5lPTEKc2V0IG5vcnVsZXIKc2V0IGxpbmVicmVhayBicmVha2luZGVudCBzaG93YnJlYWs9fjpcIAoKIiByZWxheSB2aW0ncyB0aXRsZQpzZXQgdGl0bGUgdGl0bGVzdHJpbmc9CgpzZXQgbnVtYmVyIHJlbGF0aXZlbnVtYmVyIG51bWJlcndpZHRoPTQKc2V0IGNvbG9yY29sdW1uPTgwIG5vY3Vyc29ybGluZSBub2N1cnNvcmNvbHVtbgpzZXQgbm9obHNlYXJjaAoKIiBtZXNzYWdlcyBhbmQgbWVudXMKc2V0IHNob3J0bWVzcz1hc1RJYwpzZXQgd2lsZG1lbnUgd2lsZG1vZGU9bG9uZ2VzdCxmdWxsICIgWFhYIFtOZWlsMTUsIHAuNjhdIHNldHMgYHdpbGRtb2RlPWxvbmdlc3QsbGlzdGAKCiIgW05laWwxNSwgcC4gNzBdCnNldCBoaXN0b3J5PTU1NQoKIiBsZWFkZXItYmFzZWQgYWJicmV2aWF0aW9ucwpubm9yZW1hcCA8c2lsZW50PiA8bGVhZGVyPnQgOnRlcm08Y3I+Cm5ub3JlbWFwIDxzaWxlbnQ+IDxsZWFkZXI+ciA6c2V0IHJ1bGVyITxjcj4Kbm5vcmVtYXAgPHNpbGVudD4gPGxlYWRlcj5uIDpzZXQgaGxzZWFyY2ghPGNyPgpubm9yZW1hcCA8c2lsZW50PiA8bGVhZGVyPm0gOndhPGNyPjohbWFrZTxjcj4KCiIgYDxsZWFkZXI+dWAganVtcHMgdG8gdGhlIG5leHQgbm9uLXRyaXZpYWwtYXNjaWkgY2hhcmFjdGVyIChtbmVtb25pYzogJ3RydWUgKip1KipuaWNvZGUnKQpubm9yZW1hcCA8bGVhZGVyPnUgL1teIC1+XTxjcj4KCiIgYmFuaXNoIGFycm93IGtleXMgKGFuZCBnbyBiYWNrIHRvIG5vcm1hbCBtb2RlLCBmb3JjaW5nIHRoZSB1c2VyIHRvIGNvbnRlbXBsYXRlKQpubm9yZW1hcCA8TGVmdD4gIDxOb3A+IHwgaW5vcmVtYXAgPExlZnQ+ICA8RXNjPjxOb3A+IHwgdm5vcmVtYXAgPExlZnQ+ICA8RXNjPjxOb3A+IHwgY25vcmVtYXAgPExlZnQ+ICA8RXNjPjxOb3A+Cm5ub3JlbWFwIDxSaWdodD4gPE5vcD4gfCBpbm9yZW1hcCA8UmlnaHQ+IDxFc2M+PE5vcD4gfCB2bm9yZW1hcCA8UmlnaHQ+IDxFc2M+PE5vcD4gfCBjbm9yZW1hcCA8UmlnaHQ+IDxFc2M+PE5vcD4Kbm5vcmVtYXAgPFVwPiAgICA8Tm9wPiB8IGlub3JlbWFwIDxVcD4gICAgPEVzYz48Tm9wPiB8IHZub3JlbWFwIDxVcD4gICAgPEVzYz48Tm9wPiB8IGNub3JlbWFwIDxVcD4gICAgPEVzYz48Tm9wPgpubm9yZW1hcCA8RG93bj4gIDxOb3A+IHwgaW5vcmVtYXAgPERvd24+ICA8RXNjPjxOb3A+IHwgdm5vcmVtYXAgPERvd24+ICA8RXNjPjxOb3A+IHwgY25vcmVtYXAgPERvd24+ICA8RXNjPjxOb3A+CgoiIEkgZmluZCBgcTpgIGV4Y2VlZGluZ2x5IGFubm95aW5nLgoiIFtOZWlsMTUsIHAuIDcxXTogR2l2aW5nIGl0IGFub3RoZXIgY2hhbmNlCiJub3JlbWFwIHE6IDxOb3A+Cgpubm9yZW1hcCA8bGVhZGVyPnAgOiFiYXNoIC1jICdzb3VyY2Ugfi8uYmFzaHJjICYmIHUgJiYgc2V0dXAtdmltcmMnPGNyPjpzb3VyY2Ugfi8udmltcmM8Y3I+CgoiID09PSBVU0VGVUwgPT09CiIgOmggY21kbGluZS1zcGVjaWFsCiIgYXV0b2NtZCBCdWZFbnRlciAqIDpzeW50YXggc3luYyBmcm9tc3RhcnQgIiBtYXkgc3BlbGwgdHJvdWJsZSBvbiBzbG93IHRlcm1pbmFscwoKCiIgZGlzcGxheSBzcGVjaWFsIGNoYXJhY3RlcnMKc2V0IGxpc3QgbGlzdGNoYXJzPXRhYjo+Pix0cmFpbDp+LG5ic3A6IQpsZXQgczpzaG93SW52aXNpYmxlID0gMApmdW5jdGlvbiBUb2dnbGVTaG93SW52aXNpYmxlICgpCiAgICBpZiBzOnNob3dJbnZpc2libGUKICAgICAgICBzZXQgbGlzdGNoYXJzPXRhYjo+Pix0cmFpbDp+LG5ic3A6IQogICAgICAgICIgaGkgTm9uVGV4dCAgICAgLi4uCiAgICAgICAgIiBoaSBTcGVjaWFsS2V5ICAuLi4KICAgICAgICAiIGhpIEVuZE9mQnVmZmVyIC4uLgogICAgICAgIGNvbG8gaiAiIFRPRE8KICAgIGVsc2UKICAgICAgICBzZXQgbGlzdGNoYXJzPXRhYjo+Pix0cmFpbDp+LG5ic3A6ISxzcGFjZTpfLGVvbDpgCiAgICAgICAgaGkgTm9uVGV4dCAgICAgY3Rlcm09Ym9sZCBjdGVybWZnPTIwNgogICAgICAgIGhpIFNwZWNpYWxLZXkgIGN0ZXJtPWJvbGQgY3Rlcm1mZz0yMDYKICAgICAgICBoaSBFbmRPZkJ1ZmZlciBjdGVybT1ib2xkIGN0ZXJtZmc9MjA2CiAgICBlbmQKICAgIGxldCBzOnNob3dJbnZpc2libGUgPSAhczpzaG93SW52aXNpYmxlCmVuZGZ1bmN0aW9uCm5ub3JlbWFwIDxzaWxlbnQ+IDxsZWFkZXI+aSA6Y2FsbCBUb2dnbGVTaG93SW52aXNpYmxlICgpPGNyPgoKCnN5bnRheCBvbiB8IGNvbG8gago='
    b64data_vimcolorscheme='IiBKb25hdGhhbiBGcmVjaCwgMjAyMS0wOS0yOQoKc2V0IGJhY2tncm91bmQ9ZGFyawpoaSBjbGVhcgppZiBleGlzdHMoInN5bnRheF9vbiIpCiAgICBzeW50YXggcmVzZXQKZW5kaWYKc3ludGF4IHJlc2V0CgoKIiB+fn4gR0VORVJBTCB+fn4KIiBoaWdobGlnaHRlZDogMjE0CiIgaGlnaGxpZ2h0ZWQtbm90LXNlbGVjdGVkOiAxNzIKIiBmYWludDogMjM5CiIgZmFpbnRlcjogMjM2CgoiIH5+fiBTWU5UQVggfn5+CiIgc3RyaW5nLCBjaGFyYWN0ZXI6IDcxIChzcGVjaWFsOiA3MykKIiBudW1iZXIsIGNvbnN0YW50LCBib29sZWFuOiAzNQoiIGZsb2F0OiA0MAoiIHR5cGU6IDIxMQoiIGNvbW1lbnQ6IDI0Mywgc3BlY2lhbGNvbW1lbnQ6IDI0NgoiIHN0YXRlbWVudCwgY29uZGl0aW9uYWwsIHJlcGVhdCwgc3RydWN0dXJlLCBmdW5jdGlvbjogMTAxCiIga2V5d29yZCwgbGFiZWw6IDEzNwoiIG9wZXJhdG9yLCBzdG9yYWdlY2xhc3M6IDIwMgoiIGluY2x1ZGUsIG1hY3JvLCBwcmVjb25kaXQ6IDIxMwoKIiB+fn4gVU5TVVJFIH5+fgoiIGRpcmVjdG9yeTogOTkKIiB0aXRsZQoiIHRhZwoiIDpoZWxwIGhpZ2hsaWdodC1ncm91cHMKIiBwcmVwcm9jOiAxODIKIiBUT0RPIGN1cnNvcmxpbmVucgoKImhpIFVOS05PV04gICAgICAgICAgY3Rlcm09Tm9uZSAgICBjdGVybWZnPTY0ICAgY3Rlcm1iZz0xNjUgCmhpIEJvb2xlYW4gICAgICAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9MzUgICBjdGVybWJnPU5vbmUKaGkgQ2hhcmFjdGVyICAgICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz03MSAgIGN0ZXJtYmc9Tm9uZQpoaSBDb2xvckNvbHVtbiAgICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTIxNCAgY3Rlcm1iZz0yMzkgCmhpIENvbW1lbnQgICAgICAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9MjQzICBjdGVybWJnPU5vbmUKaGkgQ29uY2VhbCAgICAgICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz02NCAgIGN0ZXJtYmc9MTY1IApoaSBDb25kaXRpb25hbCAgICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTEwMSAgY3Rlcm1iZz1Ob25lCmhpIENvbnN0YW50ICAgICAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9MzUgICBjdGVybWJnPU5vbmUKaGkgQ3Vyc29yICAgICAgICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz02NCAgIGN0ZXJtYmc9MTY1IApoaSBDdXJzb3JDb2x1bW4gICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTY0ICAgY3Rlcm1iZz0xNjUgCmhpIEN1cnNvcklNICAgICAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9NjQgICBjdGVybWJnPTE2NSAKaGkgQ3Vyc29yTGluZSAgICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz1Ob25lIGN0ZXJtYmc9MjE0IApoaSBDdXJzb3JMaW5lTnIgICAgIGN0ZXJtPUJvbGQgICAgICAgICBjdGVybWZnPU5vbmUgY3Rlcm1iZz1Ob25lCmhpIERlYnVnICAgICAgICAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9NjQgICBjdGVybWJnPTE2NSAKaGkgRGVmaW5lICAgICAgICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz02NCAgIGN0ZXJtYmc9MTY1IApoaSBEZWxpbWl0ZXIgICAgICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTIzOSAgY3Rlcm1iZz1Ob25lCmhpIERpZmZBZGQgICAgICAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9NjQgICBjdGVybWJnPTE2NSAKaGkgRGlmZkNoYW5nZSAgICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz02NCAgIGN0ZXJtYmc9MTY1IApoaSBEaWZmRGVsZXRlICAgICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTY0ICAgY3Rlcm1iZz0xNjUgCmhpIERpZmZUZXh0ICAgICAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9NjQgICBjdGVybWJnPTE2NSAKaGkgRGlyZWN0b3J5ICAgICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz05OSAgIGN0ZXJtYmc9Tm9uZQpoaSBFbmRPZkJ1ZmZlciAgICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTIzOSAgY3Rlcm1iZz1Ob25lCmhpIEVycm9yICAgICAgICAgICAgY3Rlcm09Qm9sZCAgICAgICAgIGN0ZXJtZmc9MTYwICBjdGVybWJnPTIzNSAKaGkgRXJyb3JNc2cgICAgICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz02NCAgIGN0ZXJtYmc9MTY1IApoaSBGbG9hdCAgICAgICAgICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTQwICAgY3Rlcm1iZz1Ob25lCmhpIEZvbGRDb2x1bW4gICAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9NjQgICBjdGVybWJnPTE2NSAKaGkgRm9sZGVkICAgICAgICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz02NCAgIGN0ZXJtYmc9MTY1IApoaSBGdW5jdGlvbiAgICAgICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTEwMSAgY3Rlcm1iZz1Ob25lCmhpIElkZW50aWZpZXIgICAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9MjE0ICBjdGVybWJnPU5vbmUKaGkgSWdub3JlICAgICAgICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz02NCAgIGN0ZXJtYmc9MTY1IApoaSBJbmNTZWFyY2ggICAgICAgIGN0ZXJtPUludmVyc2UsQm9sZCBjdGVybWZnPU5vbmUgY3Rlcm1iZz1Ob25lIApoaSBJbmNsdWRlICAgICAgICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTIxMyAgY3Rlcm1iZz1Ob25lCmhpIEtleXdvcmQgICAgICAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9MTM3ICBjdGVybWJnPU5vbmUKaGkgTGFiZWwgICAgICAgICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz0xMzcgIGN0ZXJtYmc9Tm9uZQpoaSBMaW5lTnIgICAgICAgICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTIxNCAgY3Rlcm1iZz1Ob25lCmhpIExpbmVOckFib3ZlICAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9MjM5ICBjdGVybWJnPU5vbmUKaGkgTGluZU5yQmVsb3cgICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz0yMzkgIGN0ZXJtYmc9Tm9uZQpoaSBNYWNybyAgICAgICAgICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTIxMyAgY3Rlcm1iZz1Ob25lCmhpIE1hdGNoUGFyZW4gICAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9MjE0ICBjdGVybWJnPTIzOSAKaGkgTW9kZU1zZyAgICAgICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz0yMzkgIGN0ZXJtYmc9Tm9uZQpoaSBNb3JlTXNnICAgICAgICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTY0ICAgY3Rlcm1iZz0xNjUgCmhpIE5vblRleHQgICAgICAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9MjM5ICBjdGVybWJnPU5vbmUKaGkgTm9ybWFsICAgICAgICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz1Ob25lIGN0ZXJtYmc9Tm9uZQpoaSBOdW1iZXIgICAgICAgICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTM1ICAgY3Rlcm1iZz1Ob25lCmhpIE9wZXJhdG9yICAgICAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9MjAyICBjdGVybWJnPU5vbmUKaGkgUG1lbnUgICAgICAgICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz0yMTQgIGN0ZXJtYmc9MjM2IApoaSBQbWVudVNiYXIgICAgICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTY0ICAgY3Rlcm1iZz0xNjUgCmhpIFBtZW51U2VsICAgICAgICAgY3Rlcm09SW52ZXJzZSAgICAgIGN0ZXJtZmc9MjE0ICBjdGVybWJnPTIzNgpoaSBQbWVudVRodW1iICAgICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTY0ICAgY3Rlcm1iZz0xNjUgCmhpIFByZUNvbmRpdCAgICAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9MjEzICBjdGVybWJnPU5vbmUKaGkgUHJlUHJvYyAgICAgICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz0xODIgIGN0ZXJtYmc9Tm9uZQpoaSBRdWVzdGlvbiAgICAgICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTY0ICAgY3Rlcm1iZz0xNjUgCmhpIFF1aWNrRml4TGluZSAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9NjQgICBjdGVybWJnPTE2NSAKaGkgUmVwZWF0ICAgICAgICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz0xMDEgIGN0ZXJtYmc9Tm9uZQpoaSBTZWFyY2ggICAgICAgICAgIGN0ZXJtPUludmVyc2UsQm9sZCBjdGVybWZnPU5vbmUgY3Rlcm1iZz1Ob25lIApoaSBTaWduQ29sdW1uICAgICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTY0ICAgY3Rlcm1iZz0xNjUgCmhpIFNwZWNpYWwgICAgICAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9MjE0ICBjdGVybWJnPU5vbmUKaGkgU3BlY2lhbENoYXIgICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz03MyAgIGN0ZXJtYmc9Tm9uZQpoaSBTdHJpbmcgICAgICAgICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTcxICAgY3Rlcm1iZz1Ob25lCmhpIFNwZWNpYWxDb21tZW50ICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9MjQ2ICBjdGVybWJnPU5vbmUKaGkgU3BlY2lhbEtleSAgICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz0yMTQgIGN0ZXJtYmc9Tm9uZQpoaSBTcGVsbEJhZCAgICAgICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTY0ICAgY3Rlcm1iZz0xNjUgCmhpIFNwZWxsQ2FwICAgICAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9NjQgICBjdGVybWJnPTE2NSAKaGkgU3BlbGxMb2NhbCAgICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz02NCAgIGN0ZXJtYmc9MTY1IApoaSBTcGVsbFJhcmUgICAgICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTY0ICAgY3Rlcm1iZz0xNjUgCmhpIFN0YXRlbWVudCAgICAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9MTAxICBjdGVybWJnPU5vbmUKaGkgU3RhdHVzTGluZSAgICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz0yMTQgIGN0ZXJtYmc9MjM5CmhpIFN0YXR1c0xpbmVOQyAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9MTcyICBjdGVybWJnPTIzNgpoaSBTdGF0dXNMaW5lVGVybSAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTY0ICAgY3Rlcm1iZz0xNjUgCmhpIFN0YXR1c0xpbmVUZXJtTkMgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9NjQgICBjdGVybWJnPTE2NSAKaGkgU3RvcmFnZUNsYXNzICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz0yMDIgIGN0ZXJtYmc9Tm9uZQpoaSBTdHJpbmcgICAgICAgICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTcxICAgY3Rlcm1iZz1Ob25lCmhpIFN0cnVjdHVyZSAgICAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9MTAxICBjdGVybWJnPU5vbmUKaGkgVGFiTGluZSAgICAgICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz02NCAgIGN0ZXJtYmc9MTY1IApoaSBUYWJMaW5lRmlsbCAgICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTY0ICAgY3Rlcm1iZz0xNjUgCmhpIFRhYkxpbmVTZWwgICAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9NjQgICBjdGVybWJnPTE2NSAKaGkgVGFnICAgICAgICAgICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz0yOSAgIGN0ZXJtYmc9Tm9uZQpoaSBUZXJtaW5hbCAgICAgICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTY0ICAgY3Rlcm1iZz0xNjUgCmhpIFRpdGxlICAgICAgICAgICAgY3Rlcm09Qm9sZCAgICAgICAgIGN0ZXJtZmc9Tm9uZSBjdGVybWJnPU5vbmUKaGkgVG9kbyAgICAgICAgICAgICBjdGVybT1Cb2xkICAgICAgICAgY3Rlcm1mZz0yMTQgIGN0ZXJtYmc9Tm9uZQpoaSBUb29sYmFyQnV0dG9uICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTY0ICAgY3Rlcm1iZz0xNjUgCmhpIFRvb2xiYXJMaW5lICAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9NjQgICBjdGVybWJnPTE2NSAKaGkgVHlwZSAgICAgICAgICAgICBjdGVybT1Ob25lICAgICAgICAgY3Rlcm1mZz0yMTEgIGN0ZXJtYmc9Tm9uZQpoaSBUeXBlZGVmICAgICAgICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTIxMSAgY3Rlcm1iZz1Ob25lICIgdXNlZCBmb3IgSGFza2VsbCdzIGB0eXBlYApoaSBVbmRlcmxpbmVkICAgICAgIGN0ZXJtPUJvbGQgICAgICAgICBjdGVybWZnPU5vbmUgY3Rlcm1iZz1Ob25lCmhpIFZlcnRTcGxpdCAgICAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9MjM5ICBjdGVybWJnPU5vbmUKaGkgVmlzdWFsICAgICAgICAgICBjdGVybT1JbnZlcnNlICAgICAgY3Rlcm1mZz1Ob25lIGN0ZXJtYmc9Tm9uZQpoaSBWaXN1YWxOT1MgICAgICAgIGN0ZXJtPU5vbmUgICAgICAgICBjdGVybWZnPTY0ICAgY3Rlcm1iZz0xNjUgCmhpIFdhcm5pbmdNc2cgICAgICAgY3Rlcm09Tm9uZSAgICAgICAgIGN0ZXJtZmc9NjQgICBjdGVybWJnPTE2NSAKaGkgV2lsZE1lbnUgICAgICAgICBjdGVybT1ib2xkICAgICAgICAgY3Rlcm1mZz0yMzkgIGN0ZXJtYmc9MjE0IAoKIiBjbGVhciBkZWZhdWx0IGxDdXJzb3IgbGluawo='
    mkdir -p "$HOME"
    printf '%s' "$b64data_vimrc" | decode-base64 > "$HOME/.vimrc"
    mkdir -p "$HOME/.vim/colors"
    printf '%s' "$b64data_vimcolorscheme" | decode-base64 > "$HOME/.vim/colors/j.vim"
}

setup-git () {
    printf 'configuring git ...\n'

    printf 'git e-mail address: '
    read email
    [ -z "$email" ] && printf 'no e-mail address given\n' && return 1
    printf 'git full name: '
    read fullname
    [ -z "$fullname" ] && printf 'no full name given\n' && return 1

    git config --global user.email "$email"
    git config --global user.name "$fullname"
    git config --global pull.rebase false
    git config --global core.editor vim
    git config --global init.defaultBranch master # alternatively, 'spiteful-supremecist-twig'

    return 0
}

setup-go () {
    echo '# [ $(id -u) = 0 ] && rm -rf /bin/go && curl -f#SL https://dl.google.com/go/go1.17.2.linux-amd64.tar.gz | tar xz -f - -C /bin'
    { error 'not implemented yet'; return 1; }
}

setup-aliases () {
    case "$(uname)" in
        'Darwin') setup-aliases-darwin ;;
        *) setup-aliases-generic-unix ;;
    esac
}
setup-aliases-generic-unix () {
    alias cp='cp -r'
    alias grep='grep --color=auto'
    alias ls='ls -pA --color=auto'
    alias open='xdg-open'
}
setup-aliases-darwin () {
    alias cp='cp -r'
    alias grep='grep --color=auto'
    alias ls='ls -AG'
}




# SSH ##########################################################################
################################################################################

setup-github-ssh () {
    keyfile="$HOME/.ssh/github"
    [ -e "$keyfile" ] && printf 'keyfile already exists: %s\n' "$keyfile" && return 1
    [ -e "$keyfile.pub" ] && printf 'keyfile.pub already exists: %s\n' "$keyfile.pub" && return 1

    [ -n "$(git config --global user.email)" ] && ! setup-git && return 1

    printf 'generating key ...\n'
    ssh-keygen -t ed25519 -f "$keyfile" -N '' -C "$(git config --global user.email)"

    printf 'you may let GitHub (\33[1m\33[94mhttps://github.com/settings/keys\33[m) know about your public key:\n    '
    cat "$keyfile.pub"
}

ssh-trust-public-key () {
    ( [ -n "$tpkf" ] && [ -d "$tpkf" ] ) || return 1

    [ $# -eq 3 ] || return 1
    name="$1"
    fingerprint="$2"
    publickey="$3"

    printf '%s\n' "$publickey" >"$name"
    ssh-keygen -lf "$name" >"$name.fingerprint"
    printf '%s\n' "$fingerprint" | cmp "$name.fingerprint" || {
        rm -f "$name" "$name.fingerprint"
        return 1
    }

    grep -qFx "$publickey" "$HOME/.ssh/known_hosts" && return 0
    printf 'trusting public ssh key: %s\n' "$name"
    echo "$publickey" >>"$HOME/.ssh/known_hosts"
}

setup-ssh-trust () {
    tpkf="$HOME/.ssh/.trusted-public-key-files"
    mkdir -p "$tpkf"
    rm -f "$tpkf"/*

    # see `https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints`
    # run `$ ssh-keyscan github.com 2>/dev/null`
    ssh-trust-public-key "$tpkf/github.com.rsa" \
        '2048 SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8 github.com (RSA)' \
        'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ=='
    ssh-trust-public-key "$tpkf/github.com.ecdsa" \
        '256 SHA256:p2QAMXNIC1TJYWeIOttrVc98/R1BUFWu3/LiyKgUfQM github.com (ECDSA)' \
        'github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg='
    ssh-trust-public-key "$tpkf/github.com.ed25519" \
        '256 SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU github.com (ED25519)' \
        'github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl'
}

load-ssh-keys () {
    # only start the ssh agent when keys exist
    [ -d "$HOME/.ssh" ] || return 1
    find "$HOME/.ssh" | grep -q '[^/]\.pub$' || return 1
    [ ! -d "$HOME/.ssh" ] && return 1

    # do not spawn too many instances
    [ -n "$SSH_AGENT_PID" ] && return

    setup-ssh-trust
    softly-write-file 'WyAtbiAiJFNTSF9BR0VOVF9QSUQiIF0gJiYgZXZhbCAiJChzc2gtYWdlbnQgLWspIgo=' "$HOME/.bash_logout"

    eval "$(ssh-agent -s)" >/dev/null
    find "$HOME/.ssh" -name '*.pub' | while read pubkey; do
        privkey="${pubkey%*.pub}"
        ssh-add "$privkey" 2>/dev/null
    done
}


# PROMPT #######################################################################
################################################################################

git-fetch-alert () {
    return 0
}

export-prompt () {
    #simple_git_indicator_unicode='$(q=$? ; git rev-parse --is-inside-work-tree >/dev/null 2>&1 && (printf "\[\33[m\]Ɣ" ; [ -n "$(git status --porcelain)" ] && printf "\[\33[91m\]𝚫" ; printf "\[\33[90m\] "); exit $q)'
    git_indicators='$(q=$? ; git rev-parse --is-inside-work-tree >/dev/null 2>&1 && { printf "\[\33[90m\]%s\[\33[m\]" "$(git branch --show-current)" ; [ -n "$(git status --porcelain)" ] && printf "\[\33[93m\]*\[\33[m\]" ; printf " "; }; exit $q)'
    head='\$'
    [ -z $EUID ] && head='#' # `$EUID` is a bash-specific feature, yet this is also a bash prompt
    colored_head='\[\e[$((92-!!$?))m\]'"$head"'\[\e[m\]'
    machine_name='$(q=$? ; git-fetch-alert ; [ -f "$HOME/.machine-name" ] && cat "$HOME/.machine-name" ; exit $q)'

    export PS1="$machine_name$git_indicators$colored_head "
}


# STARTUP ######################################################################
################################################################################

setup-environment
load-ssh-keys
export-prompt
setup-aliases

# TODO Apparently, this should enable <Ctrl>-L to clear the screen.
set -o vi ; command -v clear >/dev/null && bind -x '"\C-l": clear'


# EXPERIMENTAL #################################################################
################################################################################

idea () {
    # project scaffolding: quickly enter a timestamped idea repository's directory

    [ $# -ne 1 ] && { error 'expected exactly one argument' ; return 1; }
    [ -z "$1" ] && { error 'cannot have an empty idea' ; return 1; }
    idea="$(date +'%Y-%m-%d')_$1"
    cd "$GIT_IDEA_REPOSITORY" && mkdir "$idea" && cd "$idea"
}

template-makefile-cpp () {
    # C++ scaffolding: write a `Makefile` to the current directory

    [ $# -ne 0 ] && { error 'expected no arguments'; return 1; }
    [ -e Makefile ] && { error 'a Makefile is already present'; return 1; }
    cat >Makefile <<'EOF'
.PHONY: run
run:
	make compile
	./binary

.PHONY: compile
compile:
	touch .gitignore ; grep -Fxq '/binary' .gitignore || echo '/binary' >>.gitignore
	c++ -std=c++20 -Wall -Werror -Wextra -Wpedantic -Wswitch-enum -O3 main.cpp -o binary
EOF
}


# Jonathan Frech, 2022-05-23
# `cdp`, `cdn` and `cdi`: move along the most recent directory branch (from
# these function's invocations' points of view). `$CD_HIST` is the newest
# deepest path visited compatible with `$PWD`.
# Inspired by: https://youtu.be/6VcmqjoGc0U?t=210

cdp () {
    # cdp: Change Directory Previous

    # reset `$CD_HIST` if incompatible with `$PWD`
    case "$CD_HIST" in
        "$PWD"/*) ;;
        *) [ "$PWD" != '/' ] && CD_HIST="$PWD" ;;
    esac

    # move up and status
    cd ..
    cdi
}

cdn () {
    # cdn: Change Directory Next

    # cut off `$PWD`
    front="${CD_HIST##$PWD}"
    front="${front#/}"

    # too deep
    [ -z "$front" ] && { printf '%s\33[91m/???\33[m\n' "$PWD"; return 1; }

    # move one `/`-step forward and status
    cd "${front%%/*}"
    cdi
}

cdi () {
    # cdi: Change Directory Info

    printf '%s\33[90m%s\33[m\n' "$PWD" "${CD_HIST##$PWD}"
}

setup-inputrc () {
    # NOTE: NEVER override `\C-i`, as the ninth letter of the alphabet's
    # control escape code coincides with TAB.
    [ -e "$INPUTRC" ] && { error "setup-inputrc: $INPUTRC already present"; return 1; }
    cat >"$INPUTRC" <<'EOF'
'\C-p':'cdp\n'
'\C-n':'cdn\n'
EOF
}


################################################################################
# DEPRECATED ###################################################################
################################################################################

#command -v guix >/dev/null && { export GUIX_PROFILE="/home/j/.guix-profile" ; . "$GUIX_PROFILE/etc/profile"; }

#export-extravagant-prompt () {
#    # TODO On a Guix system, test for [ -n "$GUIX_ENVIRONMENT" ] and display `[env]` accordingly.
#    export PROMPT_COMMAND='printf "\33[90m\xe2\x80\xa2\33[m\n" && b64runc "LyogSm9uYXRoYW4gRnJlY2gsIDIwMjEtMDktMjggKi8KLyogZmwsIGZpbGwgbGluZSAtLSBmaWxsIHRoZSB3aG9sZSBsaW5lIHdpdGggZmFpbnRseQogICBjb2xvcmVkICdib3ggZHJhd2luZ3MgbGlnaHQgaG9yaXpvbnRhbCcgY2hhcmFjdGVycwogICAoZGVjaW1hbCBVbmljb2RlIGNvZGUgcG9pbnQgOTQ3MikgKi8KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3lzL2lvY3RsLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KCmludCBtYWluKCkgewogICAgc3RydWN0IHdpbnNpemUgdzsKICAgIGlvY3RsKFNURE9VVF9GSUxFTk8sIFRJT0NHV0lOU1osICZ3KTsKCiAgICBwcmludGYoIlwzM1tHXDMzWzkwbSIpOwogICAgZm9yIChpbnQgaiA9IDA7IGogPCB3LndzX2NvbDsgKytqKQogICAgICAgIHByaW50ZigiXHhlMlx4OTRceDgwIik7CiAgICBwcmludGYoIlwzM1ttIik7Cn0K"'
#    export PS1='\[\e[G\e[90m\]╭────── \[\e[m\]\w\[\e[90m\] $(q=$? ; git rev-parse --is-inside-work-tree >/dev/null 2>&1 && (printf "─── \[\e[m\]Ɣ" ; [ -n "$(git status --porcelain)" ] && printf "\[\33[91m\]𝚫" ; printf "\[\33[90m\] "); exit $q)─── \u@\h ─── \D{%Y-%m-%d %H:%M:%S} \[\e[m\]\n\[\e[90m\]╰─ \[\e[m\e[$((92-!!$?))m\]\$\[\e[m\] '
#}

#_deprecated_git-fetch-alert () {
#    currently-inside-a-git-repository || return 0
#
#    delta_in_seconds='300'
#
#    tmpdir='/tmp/git-fetch-alert'
#    repohash="$(git rev-parse --show-toplevel | sha512sum | cut -f1 -d' ')"
#    timestamp="$tmpdir/$repohash"
#    mkdir -p "$tmpdir"
#    [ ! -f "$timestamp" ] && {
#        date +'%s' >"$timestamp"; git-fetch-reminder; return 0; }
#    [ $(("$(date +'%s')" >= "$delta_in_seconds" + "$(cat "$timestamp")")) -eq 1 ] && {
#        date +'%s' >"$timestamp"; git-fetch-reminder; return 0; }
#
#    return 0
#}

#currently-inside-a-git-repository () { git rev-parse --is-inside-work-tree 1>/dev/null 2>/dev/null; }

## what an ominous message ...
#git-fetch-reminder () { printf '\33[1m\33[3m\33[38;5;208mThe wise person is a fetchful one.\33[m\n' >&2; }
#git-fetch-alert () {
#    return 0 # XXX
#
#    git rev-parse --is-inside-work-tree 1>/dev/null 2>/dev/null || return 0
#    delta_in_seconds='300'
#
#    t_remote="$(git log -1 origin/HEAD --format='%ct')"
#    t_local="$(date +'%s')"
#    [ $(("$t_remote" <= "$t_local" - "$delta_in_seconds")) -eq 1 ] && {
#        git-fetch-reminder; return 0; }
#
#    return 0
#}
