New formatting sequences for the PS1 special variable in FreeBSD 14.0-RELEASE

DISCLAIMER:
Along this thread I cannot know at large if what particularly happened to me could be in fact general, nor could I state that the workaround would be the best practice or the right thing to do in a similar case. Thus, what I'm trying to share here is to be taken as a mere contribution which may or may not work under other circumstances or scenarios and I shall not be held responsible for anything that could go wrong, that is, if you try what I've successfully did, in part or in its entirety, do at your own risk. Thank you.

Introduction
By this time it should be already old news that /bin/sh has become the new default shell instead of /bin/csh. But perhaps more subtle is that this new version of Bourne Shell has expanded support for the formatting sequences supported by the PS1 special variable as can be verified on its sh() man page. That's good news, even though I've learned to enjoy the C-Shell as well.

Is it buggy?
I very much appreciate the ability to format the prompt by using a couple of newline \n characters but unfortunately, at least up to FreeBSD 14.0-RELEASE-p4, this new support seems to have bug or I haven't yet understood how to use it correctly (in the expected way or so). IMHO it feels like a new bug. For instance, a simple sequence such as export PS1="\[\n\e[37;1m\]\h\[\e[0m\]:\[\e[36m\]\w\[\e[0m\] \\$ " works fine. :cool: But if I add a second newline, say, right before \\$ the backspace key start to misbehave. :eek: Perhaps better saying, the "bug" seems to generally happen at any other place a newline character is set (even with just a single newline character inserted) except if at the very start of the formatting sequence as I've shown above.
 
export PS1="\[\n\e[37;1m\]\h\[\e[0m\]:\[\e[36m\]\w\[\e[0m\] \\$ " works fine. :cool: But if I add a second newline, say, right before \\$ the backspace key start to misbehave.
So let's take this apart really slowly:
\[ Begin a sequence of non-printing characters
\n Newline <- THIS IS A PRINTING CHARACTER!
\e[37;1m CSI sequence for white bold foreground
\] End a sequence of non-printing characters
\h Hostname
\[ Begin a sequence of non-printing characters
\e[36m CSI sequence for Cyan foreground (bold remains on)
\] End a sequence of non-printing characters
\w Current path
\[ Begin a sequence of non-printing characters
\e[0m CSI sequence for normal foreground text
\] End a sequence of non-printing characters
A blank
\\$ $ if regular user, # if root. The double slash is necessary because otherwise it is interpreted as a shell variable in double quotes.
Another blank.

I think I see the problem, it is bold-faced above. On the other hand, if sh's prompting code (wrongly?) regards newline as a non-printing character, you may have to move the second newline also into a \[ ... \] pair.
 
...
\n Newline <- THIS IS A PRINTING CHARACTER!
...

I think I see the problem, it is bold-faced above. On the other hand, if sh's prompting code (wrongly?) regards newline as a non-printing character, you may have to move the second newline also into a \[ ... \] pair.


🤔 While \n undoubtedly produces a visual effect (which is exactly what I'm aiming for), technically it's considered as a non-printable character. This is stated, for instance, on the sh() man page and also, for instance, on the US ASCII, ANSI X3.4-1986 (ISO 646 International Reference Version).

If I put \n outside of a non-printing sequence it's merely ignored, otherwise the problem with the backspace key happens.

Perhaps I should have also shown my default console terminal settings:

$ echo $TERM
xterm-256color
$ stty
speed 9600 baud;
lflags: echoe echoke echoctl
iflags: -iutf8 🤔 (this seems new in FreeBSD 14.0-RELEASE)
oflags: tab0
cflags: cs8 -parenb
 
Sorry about not reading the sh man page carefully enough: If sh is supposed to work with \n being a non-printing character, then you have to have it inside "\[ ... \]".

In that case, you may have found a bug in sh, specifically in the way it counts how many backspaces it can do (perhaps before it has to go up a line). Suggestion: If you happen to have zsh or bash installed, try exactly the same prompt with them. Their syntax for PS1 seems to be similar to sh (it might even be identical), and if your prompts works with them but not with sh, then the bug is very obvious.
 
Looking at the stty() man page I've noticed that the new utf8 flag specifically deals with the behavior of the backspace key, although changing it does not seem to solve the issue.

I can't help wondering that if I file a bug, then at some point it would be interesting :rolleyes: to see developers debating that neither stty or sh has bugs and that's up to the user the responsibility of not setting "conflicting options"; but even so, exactly what would be in conflict and ought to be avoided? AFAIK, I just got a brand new installation with all the defaults and have just tried a single setting for enjoying the new formatting sequences support in /bin/sh.
 
But are any multibyte characters involved in your testing? Your prompt doesn't have any explicit ones, but they might be in the path being displayed. Multibyte characters = anything with a code over 0x80 = usually non-english non-ASCII codes.
 
Back
Top