#!/usr/bin/env sh
# -*- coding: utf-8-unix -*-
# This is a shebang interpreter for launching Emacs Lisp scripts with Doom's CLI
# framework preloaded, plus any environment variables it needs. Use it like so:
#
#   #!/usr/bin/env doomscript
#   (print! "Hello world!")
#
# For this to work (and to avoid an absolute path in your shebang line), this
# file must be in your $PATH:
#
#   export PATH="$HOME/.config/emacs/bin:$PATH"
#
# This isn't used for bin/doom because of this $PATH/absolute path requirement
# (and using $BASH_SOURCE to locate it would reduce its POSIX compliance), but
# this should be less of an issue for folks writing their own doomscripts.

if [ "$#" -eq 0 ]; then
    >&2 echo "Error: missing required file argument"
    exit 1
fi

case "$EMACS" in
    *term*) EMACS=emacs ;;   # in {ansi-,v}term
    *\ *) ;;
    *) EMACS="${EMACS:-emacs}"
       # Only sanity-check $EMACS if it's a path or executable, beacuse it might
       # be a full command.
       if ! type "$EMACS" >/dev/null 2>&1; then
           echo "Error: failed to run Emacs with command '$EMACS'"
           echo
           echo "Are you sure Emacs is installed and in your \$PATH?"
           exit 1
       fi >&2
       ;;
esac

# Careful not to use -Q! It implies --no-site-lisp; it omits the site-lisp
# directory from `load-path' which prevent Doom from manually loading the site
# files later. Site files are important on some systems or deployment methods
# (like Snap or NixOS).
emacs="$EMACS -q --no-site-file --batch"

# Doom respects $EMACSDIR to tell it where Doom lives. If it fails, then this is
# either isn't bash, or it's a posix shell being directly sourced with sh, which
# is unsupported.
export EMACSDIR="${EMACSDIR:-$(CDPATH='' cd -- "$(dirname -- "${BASH_SOURCE:-$0}")/.." && pwd)}"
if [ ! -f "$EMACSDIR/early-init.el" ]; then
    echo "Error: failed to load $EMACSDIR/early-init.el."
    echo
    echo "Either the file doesn't exist (indicating a broken or missing Doom install)"
    echo "or that this script is being sourced directly (which is unsupported)."
    echo
    echo "Set \$EMACSDIR to the path of an existing Doom installation."
    exit 1
fi >&2
# Inform Doom's CLI about the characteristics of the current terminal and how
# bin/doom's been invoked. Read the shebang of bin/doom for explanations.
export __DOOMSH="${__DOOMSH:-sh}"
export __DOOMPID="${__DOOMPID:-$$}"
export __DOOMSTEP="${__DOOMSTEP:-0}"
export __DOOMGEOM="${__DOOMGEOM:-$(tput cols 2>/dev/null)x$(tput lines 2>/dev/null)}"
export __DOOMGPIPE="${__DOOMGPIPE:-$__DOOMPIPE}"
export __DOOMPIPE=
[ -t 0 ] || __DOOMPIPE="${__DOOMPIPE}0"
[ -t 1 ] || __DOOMPIPE="${__DOOMPIPE}1"

# Now we're ready to execute the given script. $EMACSDIR/early-init.el is Doom's
# universal bootstrapper (and will only load the bare minimum), so it must be
# loaded first.
script="$1"
shift
$emacs --load "$EMACSDIR/early-init" \
       --load "$script" \
       -- "$@"
exit=$?

# bin/doom can request the caller emulate an execve syscall by returning a 254
# exit code and generating a (temporary) exit script to be executed afterwards.
if [ "${exit:-0}" -eq 254 ]; then
    # $TMPDIR (or $TEMP and $TMP on Windows) aren't guaranteed to have values,
    # and mktemp isn't available on all systems, but you know what is? Emacs! So
    # I rely on it to provide TMPDIR.
    export TMPDIR="${TMPDIR:-${TMP:-${TEMP:-$($emacs -Q --eval '(princ (temporary-file-directory))' 2>/dev/null)}}}"

    # /tmp may be mounted with the noexec flag, so the exit-script can't be
    # executed directly.
    sh "${TMPDIR}/doom.${__DOOMPID}.${__DOOMSTEP}.sh" "$0" "$@"
    exit="$?"
fi
exit $exit

# doomscript ends here... Unless...?
