How to create a custom terminal prompt?

can anyone guide me how can i create a good looking custom terminal prompt ?

Here is the documentation on that:

As for good looking, opinions vary :slight_smile:

1 Like

bash is what is used by default also on new installs of EndeavourOS…
But there are many ways to change how the terminal look and work.

me personally i do use https://ohmyz.sh/ also many others will burn my shell down now :wink:
But i wold suggest to start using bash and try out some prompt modifications first before you jump into changing the shell.

for a jump start… try this:

  1. https://bash-prompt-generator.org/
  2. https://ezprompt.net/
  3. https://promptgen.netlify.app/
  4. https://omar.io/ps1gen/
1 Like

I’m obligated to point out that this is BLOAT. :frog:

Zsh is a really nice shell, but not when it is all bloated up like that.

My way of doing it: Use bash. Use Konsole. Use one of the many Color Schemes and Fonts. I don’t see any benefit in more than just a subtle color, no benefit in zsh, and anyone using fish is on my weirdo list :wink:

1 Like

If you spend a lot of time in the terminal, it makes a difference. Zsh is really nice in interactive sessions and mostly compatible with Bash (both are POSIX compliant, as any shell ought to be, but Zsh supports most of Bash extensions to the standard, or something very similar). It’s faster than Bash (if you do not bloat it up with oh-my-zsh), and can be extended and configured to suit anyone’s preferences.

I use Zsh in graphical sessions with Konsole. But my user’s default shell is still Bash (for TTY and over SSH).

Fish is not POSIX compliant, so it’s just weird.

Check out starship available in Arch repos.
It’s super easy to set up, very customizable and already has a bunch of ready presets (if you don’t want to tweak it yourself)

2 Likes

Here is a thread from this forum.

What do you mean? Slower? I feel it’s very responsive.

Using oh-my-zsh in your .zshrc significantly slows down the loading of your terminal emulator.

Since I launch Konsole at least 50 times a day (probably much more), I want it to be as close to instantaneous as possible. I want to press the keyboard shortcut I use for it (Meta+<, which on an ISO keyboard I can just press with one finger) and I want the shell prompt to be ready and willing to accept my commands before my finger is even lifted from the key. No noticeable delay, pretty much instantaneous.

I achieve that by manually writing and optimising my .zshrc and not using any third-party bloat.

Oh-my-zsh is only good for one thing: stealing small fragments of code from it.

1 Like

I’m using it with p10k and never noticed any delay…

If you need to know how fast is zsh start, there’s a benchmark from Roman Perepelitsa here :

Lets exchange some code on this topic. Here is how I build my prompt in either bash or zsh:

function is_shell() {
    # which shell are we running in?
    # variable $SHELL is not sufficient
    # it stays on value 'zsh' if bash was started from zsh prompt
    local CURRENT_SHELL=$(ps -hp $$ | sed 's#.*\b\(.*sh\)#\1#')
    # $1 must be a shell name like "bash" or "zsh"
    if [[ $CURRENT_SHELL == "$1" ]]; then
        return 0
    else
        return 1
    fi
}

# set boolean variable to identify the shell
this_is_zsh=0
this_is_bash=0
if is_shell zsh; then
    this_is_zsh=1
    setopt shwordsplit
else
    if is_shell bash; then
        this_is_bash=1
    fi
fi

function my-prompt() {
    # color numbers
    _blue="39"
    _orange="208"
    _red="196"
    _grey="245"

    if ((this_is_bash)); then
        BLUE="$(tput setaf $_blue)"
        ORANGE="$(tput setaf $_orange)"
        RED="$(tput setaf $_red)"
        GREY="$(tput setaf $_grey)"
        RESET="$(tput init)"
    elif ((this_is_zsh)); then
        # https://zsh.sourceforge.io/Doc/Release/Zsh-Line-Editor.html#Character-Highlighting
        BLUE="%F{$_blue}"
        ORANGE="%F{$_orange}"
        RED="%F{$_red}"
        GREY="%F{$_grey}"
        RESET="%F{reset}"
    fi

    if ((EUID == 0)); then
        # this is root
        UCOLOR=${RED}
    else
        UCOLOR=${BLUE}
    fi

    if ((this_is_bash)); then
        PROMPT_COMMAND="echo"
        PS1='${UCOLOR}╭─[\u@${ORANGE}\h (bash)${UCOLOR}] $(pwd)\n╰─#${RESET} '
    elif ((this_is_zsh)); then
        function set_win_title() {
            echo -ne "\033]0; [$USER@$HOST] ${PWD/$HOME/~} \007"
        }
        precmd_functions+=(set_win_title)
        precmd() { echo; }
        if [[ $TERM == "linux" ]]; then
            # tty is not good for special character "╭─" and "╰─"
            PROMPT=$'${UCOLOR}[%n@${ORANGE}%m${UCOLOR}] %d\n#${RESET} '
        else
            PROMPT=$'${UCOLOR}╭─[%n@${ORANGE}%m${UCOLOR}] %d\n╰─#${RESET} '
        fi
    fi
}

The function is_shell is a helper function to determine the running shell. I know there is the $SHELL envrionment variable, but this is not accurate enough. If I am in zsh the variable shows zsh. If I then start bash inside a zsh session, the variable still shows zsh although I am running bash now. I am not sure if my is_shell function is the most effective way to determine the running shell, but at least it works. feedback welcome.

The function my-prompt actually creates the prompt. It works for bash or zsh.

PS
If you want to know the numbers of the available colors, you can use this function:

function display_colors() {
    if [[ $1 ]]; then
        # print one line with the given color
        tput setaf $1
        tput setab $1 ${y// /=}$x
    else
        # print all possible color; one per line
        (
            x=$(tput op) y=$(printf %76s)
            for i in {0..256}; do
                o=00$i
                echo -e ${o:${#o}-3:3} $(
                    tput setaf $i
                    tput setab $i
                )${y// /=}$x
            done
        )
    fi
}

Without argument it displays all 256 colors, one per line. With a number as argument it displays the color for that number.