In bash, how do I encode zero-width sequences into PS1, when those sequences are coming from stdout of an external process or function? How do I implement writes-prompt-sequences-to-stdout
so that it can emit multi-colored text to the prompt?
PS1='$( writes-prompt-sequences-to-stdout )'
I know that, when writing a bash PS1 prompt, I must wrap zero-width sequences in \[
\]
so bash can compute correct prompt width.
PS1='\[\e[0;35m\]$ \[\e[00m\]'
bash does not print the \[
\]
and understands the prompt is only 2 characters wide.
How do I move those sequences into an external function? The following does not work, my prompt looks like \[\]$ \[\]
, even though I can run render-prompt
and see it writing the correct sequence of bytes to stdout.
PS1='$( render-prompt )'
function render-prompt {
printf '\[\e[0;35m\]$ \[\e[00m\]'
}
Moving the printf call into PS1 does work:
PS1='$( printf '"'"'\[\e[0;35m\]$ \[\e[00m\]'"'"' )'
I theorized, perhaps bash is scanning the PS1 string before execution to count the number of zero-width bytes. So I tried tricking it by encoding [] sequences that aren't printed, but it correctly ignores the trick.
PS1='$( printf '"'"'$$$$$'"'"' '"'"'\[\e[00m\]'"'"' )'
My question:
How do I write \[
\]
sequences to stdout from a function or binary that is invoked via PS1?