Bash command history problems with long commands

I might have found a solution to this problem. To recap, my original prompt had special characters which did not print, such as changing colors and line feeds. @hdd-gehrke clued me in that I needed to surround these non-printing characters, and the variables I used to reference them, with “\[” and “\]”. These special characters told bash to not count the enclosed characters when computing the prompt length. I did so, and this worked well, except that there was still one extra non-printing character that wasn’t being accounted for. When I would scroll back through my command history and come across a longer command, the first character of that command would “stick” to the end of my prompt. This was still annoying, but better than it was before.

I guessed that the linefeed character “\n” was the problem, because in Linux this one character handles both linefeed and carriage return, so perhaps under the hood it was being translated into two special characters. I could find I could issue a carriage return with “\r”, but couldn’t find an escape character for a line feed alone without a carriage return.

Today, I had an idea to enclose a normal, printing character within the non-printing counting brackets, as a way to fool the underlying bash prompt engine as to what the real prompt length is. I did so with the final colon as the non-printing (but really printing) character. In my short, 15 minutes of testing, my prompt is now behaving exactly as I want it.

Here’s what my prompt string looks like now:

PS1=“\[${IYellow}\]\[${On_Blue}\][\w]\[$Color_Off\]\[\n\]\[${IWhite}\]\[${On_Blue}\][\h-\u]\[:\]\[$Color_Off\]”

I know it looks confusing as spaghetti code, but that’s what does the job. I tried combining bracketing between adjacent non-printing characters, such as "\[${IYellow}${On_Blue}\], but that didn’t work. I will give it another day or two of testing before accepting this solution, if in fact it continues to behave properly.