mirror of https://github.com/curusarn/resh
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
218 lines
8.1 KiB
218 lines
8.1 KiB
#!/hint/sh
|
|
|
|
# BACKWARDS COMPATIBILITY NOTES:
|
|
#
|
|
# Stable names and options:
|
|
# * `resh-collect -version` / `resh-postcollect -version` is used to detect version mismatch.
|
|
# => The go-like/short `-version` option needs to exist for new resh-(post)collect commands in all future version.
|
|
# => Prefer using go-like/short `-version` option so that we don't have more options to support indefinitely.
|
|
# * `__resh_preexec <CMDLINE>` with `__RESH_NO_RELOAD=1` is called on version mismatch.
|
|
# => The `__resh_preexec` function needs to exist in all future versions.
|
|
# => Make sure that `__RESH_NO_RELOAD` behavior is not broken in any future version.
|
|
# => Prefer only testing `__RESH_NO_RELOAD` for emptyness instead of specific value
|
|
# * `__resh_reload_msg` is called *after* shell files reload
|
|
# => The function shows a message from the already updated shell files
|
|
# => We can drop this function at any time - the old version will be used
|
|
|
|
# Backwards compatibilty: Please see notes above before making any changes here.
|
|
__resh_reload_msg() {
|
|
printf '\n'
|
|
printf '+--------------------------------------------------------------+\n'
|
|
printf '| New version of RESH shell files was loaded in this terminal. |\n'
|
|
printf '| This is an informative message - no action is necessary. |\n'
|
|
printf '| Please restart this terminal if you encounter any issues. |\n'
|
|
printf '+--------------------------------------------------------------+\n'
|
|
printf '\n'
|
|
}
|
|
|
|
# (pre)collect
|
|
# Backwards compatibilty: Please see notes above before making any changes here.
|
|
__resh_preexec() {
|
|
if [ "$(resh-collect -version)" != "$__RESH_VERSION" ] && [ -z "${__RESH_NO_RELOAD-}" ]; then
|
|
# Reload shell files and restart __resh_preexec - i.e. the full command will be recorded only with a slight delay.
|
|
# This should happens in every already open terminal after resh update.
|
|
# __RESH_NO_RELOAD prevents recursive reloads
|
|
# We never repeatadly reload the shell files to prevent potentially infinite recursion.
|
|
# If the version is still wrong then error will be raised by `resh-collect -requiredVersion`.
|
|
|
|
source ~/.resh/shellrc
|
|
# Show reload message from the updated shell files
|
|
__resh_reload_msg
|
|
# Rerun self but prevent another reload. Extra protection against infinite recursion.
|
|
__RESH_NO_RELOAD=1 __resh_preexec "$@"
|
|
return $?
|
|
fi
|
|
__RESH_COLLECT=1
|
|
__RESH_RECORD_ID=$(resh-generate-uuid)
|
|
# TODO: do this in resh-collect
|
|
# shellcheck disable=2155
|
|
local git_remote="$(git remote get-url origin 2>/dev/null)"
|
|
# TODO: do this in resh-collect
|
|
__RESH_RT_BEFORE=$(resh-get-epochtime)
|
|
resh-collect -requireVersion "$__RESH_VERSION" \
|
|
--git-remote "$git_remote" \
|
|
--home "$HOME" \
|
|
--pwd "$PWD" \
|
|
--record-id "$__RESH_RECORD_ID" \
|
|
--session-id "$__RESH_SESSION_ID" \
|
|
--session-pid "$$" \
|
|
--shell "$__RESH_SHELL" \
|
|
--shlvl "$SHLVL" \
|
|
--time "$__RESH_RT_BEFORE" \
|
|
--cmd-line "$1"
|
|
return $?
|
|
}
|
|
|
|
# postcollect
|
|
# Backwards compatibilty: Please see notes above before making any changes here.
|
|
__resh_precmd() {
|
|
# Get status first before it gets overriden by another command.
|
|
local exit_code=$?
|
|
# Don't do anything if __resh_preexec was not called.
|
|
# There are situations (in bash) where no command was submitted but __resh_precmd gets called anyway.
|
|
[ -n "${__RESH_COLLECT-}" ] || return
|
|
if [ "$(resh-postcollect -version)" != "$__RESH_VERSION" ]; then
|
|
# Reload shell files and return - i.e. skip recording part2 for this command.
|
|
# We don't call __resh_precmd because the new __resh_preexec might not be backwards compatible with variables set by old __resh_preexec.
|
|
# This should happen only in the one terminal where resh update was executed.
|
|
# And the resh-daemon was likely restarted so we likely don't even have the matching part1 of the comand in the resh-daemon memory.
|
|
source ~/.resh/shellrc
|
|
# Show reload message from the updated shell files
|
|
__resh_reload_msg
|
|
return
|
|
fi
|
|
unset __RESH_COLLECT
|
|
|
|
# do this in resh-postcollect
|
|
# shellcheck disable=2155
|
|
local rt_after=$(resh-get-epochtime)
|
|
resh-postcollect -requireVersion "$__RESH_VERSION" \
|
|
--exit-code "$exit_code" \
|
|
--record-id "$__RESH_RECORD_ID" \
|
|
--session-id "$__RESH_SESSION_ID" \
|
|
--shlvl "$SHLVL" \
|
|
--time-after "$rt_after" \
|
|
--time-before "$__RESH_RT_BEFORE"
|
|
return $?
|
|
}
|
|
|
|
# Backwards compatibilty: No restrictions. This is only used at the start of the session.
|
|
__resh_session_init() {
|
|
resh-session-init -requireVersion "$__RESH_VERSION" \
|
|
--session-id "$__RESH_SESSION_ID" \
|
|
--session-pid "$$"
|
|
return $?
|
|
}
|
|
|
|
# Backwards compatibilty: Please see notes above before making any changes here.
|
|
__resh_widget_control_R() {
|
|
# This is a very bad workaround.
|
|
# Force bash-preexec to run repeatedly because otherwise premature run of bash-preexec overshadows the next proper run.
|
|
# I honestly think that it's impossible to make widgets work in bash without hacks like this.
|
|
# shellcheck disable=2034
|
|
__bp_preexec_interactive_mode="on"
|
|
|
|
local PREVBUFFER=$BUFFER
|
|
|
|
local status_code
|
|
local git_remote; git_remote="$(git remote get-url origin 2>/dev/null)"
|
|
if [ "$(resh-cli -version)" != "$__RESH_VERSION" ] && [ -z "${__RESH_NO_RELOAD-}" ]; then
|
|
source ~/.resh/shellrc
|
|
# Show reload message from the updated shell files
|
|
__resh_reload_msg
|
|
# Rerun self but prevent another reload. Extra protection against infinite recursion.
|
|
__RESH_NO_RELOAD=1 __resh_widget_control_R "$@"
|
|
return $?
|
|
fi
|
|
BUFFER=$(resh-cli -requireVersion "$__RESH_VERSION" \
|
|
--git-origin-remote "$git_remote" \
|
|
--pwd "$PWD" \
|
|
--query "$BUFFER" \
|
|
--session-id "$__RESH_SESSION_ID" \
|
|
)
|
|
status_code=$?
|
|
if [ $status_code = 111 ]; then
|
|
# execute
|
|
if [ -n "${ZSH_VERSION-}" ]; then
|
|
# zsh
|
|
zle accept-line
|
|
elif [ -n "${BASH_VERSION-}" ]; then
|
|
# bash
|
|
# set chained keyseq to accept-line
|
|
bind '"\u[32~": accept-line'
|
|
fi
|
|
elif [ $status_code = 0 ]; then
|
|
if [ -n "${BASH_VERSION-}" ]; then
|
|
# bash
|
|
# set chained keyseq to nothing
|
|
bind -x '"\u[32~": __resh_nop'
|
|
fi
|
|
else
|
|
echo "RESH SEARCH APP failed"
|
|
printf "%s" "$buffer" >&2
|
|
BUFFER="$PREVBUFFER"
|
|
fi
|
|
CURSOR=${#BUFFER}
|
|
}
|
|
|
|
# Wrapper for resh-cli for calling resh directly
|
|
resh() {
|
|
if [ "$(resh-cli -version)" != "$__RESH_VERSION" ] && [ -z "${__RESH_NO_RELOAD-}" ]; then
|
|
source ~/.resh/shellrc
|
|
# Show reload message from the updated shell files
|
|
__resh_reload_msg
|
|
# Rerun self but prevent another reload. Extra protection against infinite recursion.
|
|
__RESH_NO_RELOAD=1 resh "$@"
|
|
return $?
|
|
fi
|
|
local buffer
|
|
local git_remote; git_remote="$(git remote get-url origin 2>/dev/null)"
|
|
buffer=$(resh-cli -requireVersion "$__RESH_VERSION" \
|
|
--git-origin-remote "$git_remote" \
|
|
--pwd "$PWD" \
|
|
--session-id "$__RESH_SESSION_ID" \
|
|
"$@"
|
|
)
|
|
status_code=$?
|
|
if [ $status_code = 111 ]; then
|
|
# execute
|
|
echo "$buffer"
|
|
eval "$buffer"
|
|
elif [ $status_code = 0 ]; then
|
|
# paste
|
|
echo "$buffer"
|
|
elif [ $status_code = 130 ]; then
|
|
true
|
|
else
|
|
printf "%s" "$buffer" >&2
|
|
fi
|
|
}
|
|
|
|
__resh_widget_control_R_compat() {
|
|
__bindfunc_compat_wrapper __resh_widget_control_R
|
|
}
|
|
|
|
__resh_nop() {
|
|
# does nothing
|
|
true
|
|
}
|
|
|
|
# shellcheck source=../submodules/bash-zsh-compat-widgets/bindfunc.sh
|
|
. ~/.resh/bindfunc.sh
|
|
|
|
__resh_bind_control_R() {
|
|
bindfunc '\C-r' __resh_widget_control_R_compat
|
|
if [ -n "${BASH_VERSION-}" ]; then
|
|
# fuck bash
|
|
bind '"\C-r": "\u[31~\u[32~"'
|
|
bind -x '"\u[31~": __resh_widget_control_R_compat'
|
|
|
|
# execute
|
|
# bind '"\u[32~": accept-line'
|
|
|
|
# just paste
|
|
# bind -x '"\u[32~": __resh_nop'
|
|
true
|
|
fi
|
|
return 0
|
|
}
|
|
|