4

I want to use an American flag emoji in my bash prompt (i.e. PS1 environment variable). However, the American flag emoji causes the terminal cursor to offset an extra character to the right.

is comprised of two unicode characters, and . I believe terminal is converting this to a mono-spaced emoji character (the flag), yet still allocating space for two characters. How can I achieve my expected cursor position?

I want:
Desktop akirna ls|

I get:
Desktop akirna ls | << weird space offset before cursor

My ~/.bash_profile is:

export PS1='  \W \u  '
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
Andrew Kirna
  • 1,346
  • 16
  • 18
  • 3
    [so] is for programming questions, not questions about using or configuring Linux and its applications. [su] or [unix.se] would be better places for questions like this. – Barmar Jan 31 '19 at 00:48
  • See this [unix.se] question: https://unix.stackexchange.com/questions/239041/bash-prompt-not-wrapping-as-expected/294069#294069 – Barmar Jan 31 '19 at 00:49
  • @Barmar, thanks, but that answer didn't help. I posted on Unix & Linux [here](https://unix.stackexchange.com/questions/497826/how-can-i-properly-use-an-american-flag-emoji-in-my-bash-prompt) – Andrew Kirna Jan 31 '19 at 01:10
  • Try [this](https://stackoverflow.com/questions/13459913/how-to-add-an-icon-to-the-bash-prompt) – Barmar Jan 31 '19 at 01:15
  • @Barmar, I used the suggested hexdump for an American flag but the PS1 prompt just shows the hexdump code. `export PS1='\[\xf0\x9f\x87\xba\xf0\x9f\x87\xb8\] \W \u '` shows `\xf0\x9f\x87\xba\xf0\x9f\x87\xb8 ~ akirna ` – Andrew Kirna Jan 31 '19 at 15:36
  • MacOS has bash 3, that answer says it works in bash 4. – Barmar Jan 31 '19 at 18:08
  • I’m running bash 4.4.23 – Andrew Kirna Jan 31 '19 at 19:02
  • Looks like it doesn't understand hex, you need to use octal. But I don't think any of this really solves the problem. There's no way to tell bash that multiple bytes only use one column. `\[` can be used for sequences that take no space at all, but everything else is assumed to be 1 for 1. – Barmar Jan 31 '19 at 19:21
  • Exactly. Even \[\] to ignore the space of different characters didn’t work. – Andrew Kirna Jan 31 '19 at 19:55
  • maybe try `\001` and `\002` instead of `\[` and `\]`: https://unix.stackexchange.com/a/447520/103120 – phil294 Feb 01 '19 at 11:01
  • @Blauhirn, thanks but that didn't work. – Andrew Kirna Feb 01 '19 at 19:57
  • here is what Im using in my terminal and it is working just fine (the vars in command are for sake of easy reading for me): `export PS1=" $BPurple$gitBranch$BRed$PathShort$NewLine$BBlue$Dollar$Color_Off"` if you want I can provide their values as well – BigGinDaHouse Feb 13 '19 at 06:24
  • @BigGinDaHouse, my problem arises from the American flag registering two spaces wide, while it should only take one. This causes a weird offset; i.e. text input appears one space before the cursor – Andrew Kirna Feb 19 '19 at 18:42
  • Just because the place a question is on-topic doesn't provide an answer doesn't make it permissible places it's off-topic. – Charles Duffy Apr 16 '19 at 01:07

2 Answers2

2

Updated Answer

The way your are setting the prompt is not evaluating the escape characters. Add a $ before the string to make it evaluate the escape codes:

pompt$ export PS1='XY \x08: '
XY \x08: echo "Well that didn't work..."

Should become:

pompt$ export PS1=$'XY \x08: '
XY: echo "Escape code success!"

(See Charles Duffy's comment on this answer for why I removed export.)

The example above sets the prompt to the characters X, Y, [space], [backspace], [colon] resulting in a displayed prompt of just "XY:".

On my system, the flag is rendered as two characters ( and ), so I cannot verify this, but I think adding a backspace (\x08) should work for you:

PS1=$'  \\W \\u \x08'

Notes about edits

My original answer suggested using a sub-shell as follows:

export PS1=$(printf "XY \x08")

Many thanks to Charles Duffy for his input~

Josh
  • 51
  • 6
  • 1
    There's no reason whatsoever to prefer `PS1=$(printf "XY \x08")` over `PS1=$'XY \x08'`, [ANSI C-like string literal syntax](https://wiki-dev.bash-hackers.org/syntax/quoting#ansi_c_like_strings). – Charles Duffy Apr 16 '19 at 01:08
  • 1
    ...and note that generally speaking, `export`ing `PS1` is not a great idea; that puts it into the environment for *all* shells -- including dash, zsh, etc -- to inherit should they be started as a subprocess of a shell running the `export`. If you just set `PS1=whatever` with no `export` in your `.bashrc`, it stays local to interactive shells sourcing that file. – Charles Duffy Apr 16 '19 at 01:09
0

I worked around this by converting the character to hex, and then putting zero width markers around the second part of the character

so for we get

PS1='\xf0\x9f\x87\xba\[\xf0\x9f\x87\xb8\] '
mcfedr
  • 7,845
  • 3
  • 31
  • 27