Created
February 23, 2022 21:51
-
-
Save gagata/d9b48d8c3037e8a57abbd87f3b534155 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
warp_escape_ps1 () { | |
tr '\n\n' ' ' <<< "$*" | xxd -p | tr -d '\n' | |
} | |
# Format a string value according to JSON syntax - Adapted from https://github.com/lework/script. | |
warp_escape_json () { | |
# Explanation of the sed replacements (each command is separated by a `;`): | |
# s/(["\\])/\\\1/g - Replace all double-quote (") and backslash (\) characters with the escaped versions (\" and \\) | |
# s/\b/\\b/g - Replace all backspace characters with \b | |
# s/\t/\\t/g - Replace all tab characters with \t | |
# s/\f/\\f/g - Replace all form feed characters with \f | |
# s/\r/\\r/g - Replace all carriage return characters with \r | |
# $!s/$/\\n/ - On every line except the last, insert the \n escape at the end of the line | |
# Note: sed acts line-by-line, so it doesn't see the literal newline characters to replace | |
# | |
# tr -d '\n' - Remove the literal newlines from the final output | |
# | |
# Additional note: In a shell script between single quotes ('), no escape sequences are interpreted. | |
# To work around that and insert the literal values into the regular expressions, we stop the single-quote, | |
# then add the literal using ANSI-C syntax ($'\t'), then start a new single-quote. That is the meaning | |
# behind the various `'$'\b''` blocks in the command. All of these separate strings are then concatenated | |
# together to form the full argument to send to sed. | |
sed -E 's/(["\\])/\\\1/g; s/'$'\b''/\\b/g; s/'$'\t''/\\t/g; s/'$'\f''/\\f/g; s/'$'\r''/\\r/g; $!s/$/\\n/' <<<"$*" | tr -d '\n' | |
} | |
warp_precmd () { | |
# $? is relative to the process so we MUST check this first | |
# or else the exit code will correspond to the commands | |
# executed within this block instead of the actual last | |
# command that was run. | |
local exit_code=$? | |
# Clear the prompt again before the command is rendered as it could | |
# have been reset by the user's bashrc or by setting the variable | |
# on the command line. | |
if [[ -n $PS1 ]]; then | |
WARP_PS1="$PS1" | |
fi | |
unset PS1 | |
unset PROMPT | |
# Escaped PS1 variable | |
local escaped_ps1 | |
if [[ $WARP_FEATURE_FLAG_HONOR_PS1 == "1" ]]; then | |
# Tricking the shell into rendering the prompt | |
# Note that in more modern versions of bash we could use ${PS1@P} to achieve the same, | |
# but macOs comes by default with a much older version of bash, and we want to be compatible. | |
deref_ps1=$(echo -e "\n" | PS1="$WARP_PS1" bash --norc -i 2>&1 | head -2 | tail -1) | |
escaped_ps1=$(warp_escape_ps1 "$(echo "$deref_ps1")") | |
fi | |
# Flush history | |
history -a | |
# Reset the custom kill-whole-line binding as the user's bashrc (which is sourced after bashrc_warp) | |
# could have added another bind. This won't have any user-impact because these shortcuts are only run | |
# in the context of the bash editor, which isn't displayed in Warp. | |
bind -r '"\C-p"' | |
bind "\C-p":kill-whole-line | |
local escaped_pwd | |
escaped_pwd=$(warp_escape_json "$PWD") | |
local escaped_virtual_env="" | |
if [ ! -z "$VIRTUAL_ENV" ]; then | |
escaped_virtual_env=$(warp_escape_json "$VIRTUAL_ENV") | |
fi | |
local escaped_conda_env="" | |
if [ ! -z "$CONDA_DEFAULT_ENV" ]; then | |
escaped_conda_env=$(warp_escape_json "$CONDA_DEFAULT_ENV") | |
fi | |
local git_branch | |
git_branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "") | |
local escaped_git_branch | |
escaped_git_branch=$(warp_escape_json "$git_branch") | |
# At this point, escaped prompt looks something like | |
# \\u{001B}\\u{005B}\\u{0030}\\u{0031}\\u{003B} ... | |
# We need to maintain the double quoting of \\u in the message that | |
# is sent otherwise the receiving side will interpret the value | |
# as JS string literals of the form \uHEX, and will include | |
# ctrl characters (like ESC) in the json, which will cause a JSON | |
# parse error. | |
# Note WARP_SESSION_ID doesn't need to be escaped since it's a number | |
local escaped_json="{\"hook\": \"Precmd\", \"value\": {\"pwd\": \"$escaped_pwd\", \"ps1\": \"$escaped_ps1\", \"git_branch\": \"$escaped_git_branch\", \"virtual_env\": \"$escaped_virtual_env\", \"conda_env\": \"$escaped_conda_env\", \"exit_code\": $exit_code, \"session_id\": $WARP_SESSION_ID}}" | |
warp_send_message "$escaped_json" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment