bash: add primary and secondary marks to PS1 and PS2

These OSC 133 semantic prompt sequences mark the primary and secondary
parts of the prompt strings.

PS1 is marked as the primary (initial) prompt. This is the default, so
we could skip emitting these sequences, but they're added here for now
to be explicit and consistent with what other terminal emulators do in
their shell integrations.

If PS1 is a multiline prompt (i.e. it contains a newline), we mark the
last line as a secondary prompt (k=s). bash doesn't redraw the leading
lines of a multiline prompt on its own, so we can use this information
at runtime to prevent the preceding lines from being erased by ghostty
after a resize.

PS2 is always marked as a secondary prompt.
This commit is contained in:
Jon Parise
2024-07-19 07:20:13 -04:00
parent 1eb18895bf
commit 2bf1f80f77

View File

@ -98,8 +98,19 @@ function __ghostty_precmd() {
_GHOSTTY_SAVE_PS2="$PS2"
# Marks
PS1=$PS1'\[\e]133;B\a\]'
PS2=$PS2'\[\e]133;B\a\]'
PS1='\[\e]133;P;k=i\a\]'$PS1'\[\e]133;B\a\]'
PS2='\[\e]133;P;k=s\a\]'$PS2'\[\e]133;B\a\]'
if [[ "${PS1}" == *"\n"* || "${PS1}" == *$'\n'* ]]; then
# bash doesn't redraw the leading lines in a multiline prompt so
# mark the last line as a secondary prompt (k=s) to prevent the
# preceding lines from being erased by ghostty after a resize.
builtin local oldval
oldval=$(builtin shopt -p extglob)
builtin shopt -s extglob
PS1=${PS1%@('\n'|$'\n')*}'\n\[\e]133;P;k=s\a\]'${PS1##*@('\n'|$'\n')}
builtin eval "$oldval"
fi
# Cursor
if test "$GHOSTTY_SHELL_INTEGRATION_NO_CURSOR" != "1"; then