mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2024-11-14 23:14:05 -08:00
83 lines
4.6 KiB
Plaintext
83 lines
4.6 KiB
Plaintext
|
---
|
||
|
title: "Deprecating the bash rprompt"
|
||
|
description: "Deprecating the bash rprompt"
|
||
|
slug: deprecating-bash-rprompt
|
||
|
authors:
|
||
|
- name: Jan De Dobbeleer
|
||
|
title: Maintainer
|
||
|
url: https://github.com/jandedobbeleer
|
||
|
image_url: https://avatars.githubusercontent.com/u/2492783?v=4
|
||
|
tags: [breaking, ohmyposh]
|
||
|
hide_table_of_contents: false
|
||
|
---
|
||
|
|
||
|
After careful consideration, it was decided to remove support for the [`rprompt`][rprompt] in bash. If you are
|
||
|
interested in the reasons behind this decision, please read on.
|
||
|
|
||
|
<!--truncate-->
|
||
|
## Context
|
||
|
|
||
|
[`rprompt`][rprompt] is a feature that allows you to display a prompt at the right side of the terminal, on
|
||
|
the same line as your cursor. This feature is available natively on a lot of shells, but not on bash.
|
||
|
To work around this limitation, Oh My Posh has a **custom implementation** we use for both bash and PowerShell.
|
||
|
|
||
|
## History
|
||
|
|
||
|
### First implementation
|
||
|
|
||
|
There were two evolutions of bash' custom [`rprompt`][rprompt] in Oh My Posh. The first one printed the [`rprompt`][rprompt]
|
||
|
together with the primany prompt in the `PS1` variable, so we only need one CLI call to visualize the prompt.
|
||
|
|
||
|
The challenge is that, as the [`rprompt`][rprompt] is printed together with the primary prompt, we need to make sure
|
||
|
bash' readline can interprete the prompt correctly. In bash, every character that isn't a printable character,
|
||
|
like color codes, needs to be wrapped in `\[` and `\]`. This is necessary to make sure bash can **calculate the length**
|
||
|
of the prompt and ultimately **position the cursor** correctly.
|
||
|
|
||
|
It turned out that for [`rprompt`][rprompt], this _needed to be done differently_. The [`rprompt`][rprompt] is printed after what
|
||
|
bash interpretes as the end of the prompt. We found out that we need to wrap the entire [`rprompt`][rprompt] in `\[` and `\]`,
|
||
|
and not escape individual non-printable characters.
|
||
|
|
||
|
We did that for a while, but apparently this approach was **not very robust**. It was easy to break readline's
|
||
|
cursor position calculation, and it was hard to debug. The behaviour of this was also different cross platform,
|
||
|
so we had to go back to the drawing board.
|
||
|
|
||
|
### Second implementation
|
||
|
|
||
|
The second implementation of the [`rprompt`][rprompt] was a lot more robust. We decided to print the [`rprompt`][rprompt] in a separate
|
||
|
CLI call, so we could control the output more easily. It leveraged the use of the `PROMPT_COMMAND` variable in bash, which
|
||
|
is a hook that is executed before the prompt is printed. We would first print the [`rprompt`][rprompt] in the `PROMPT_COMMAND`,
|
||
|
and then set the primary prompt in the `PS1` variable so bash would not bother about the [`rprompt`][rprompt] being there.
|
||
|
|
||
|
This approach was a lot **cleaner from an achitectural point of view**, but it had some downsides.
|
||
|
The biggest downside was needing two CLI calls to print the prompt, which is not a big issue,
|
||
|
but it was a bit slower than the first implementation.
|
||
|
|
||
|
Additionally, as we print before `PS1` is evaluated, it introduced the following issues:
|
||
|
|
||
|
1. when the output of the previous command didn't end with a newline, the [`rprompt`][rprompt] would be printed on the same line
|
||
|
as the output of the previous command
|
||
|
2. when the prompt was at the bottom of the terminal buffer, the [`rprompt`][rprompt] would be printed on the same line as the
|
||
|
prompt, which would break the prompt
|
||
|
3. depending on the platform, it would still break command history navigation
|
||
|
4. it required different logic for multiline prompts as we print before `PS1` and need to reposition the cursor correctly
|
||
|
|
||
|
Of these issues, **only bullet 4 could be fixed**. Everything else was out of our control.
|
||
|
|
||
|
## Conclusion
|
||
|
|
||
|
Oh My Posh is a tool that needs to be easy to use, maintain and be 100% reliable. One of the core principles of Oh My Posh is that it should
|
||
|
**never break the shell**. The [`rprompt`][rprompt] feature in bash has never been reliable enough, and it was _hard to debug_ when it broke.
|
||
|
I have spent countless hours debugging issues with the [`rprompt`][rprompt] in bash, but it's **time to move on**. If you
|
||
|
want to use the [`rprompt`][rprompt] feature, I would recommend using a shell that supports it natively, like [nushell], [zsh] or [fish].
|
||
|
|
||
|
## What about Powershell?
|
||
|
|
||
|
The [`rprompt`][rprompt] feature in PowerShell is **100% reliable**, even if it's not natively supported. PowerShell doesn't
|
||
|
have the same challenges calculating the actual prompt width like bash, there's _no need to escape anything_.
|
||
|
We can use the first implementation mentioned above, and it works like a charm.
|
||
|
|
||
|
[rprompt]: /docs/configuration/block#type
|
||
|
[nushell]: https://www.nushell.sh/
|
||
|
[zsh]: https://www.zsh.org/
|
||
|
[fish]: https://fishshell.com/
|