Removing the useless space at the end of the right prompt of zsh ($RPROMPT)

TL;DR

All you need to do is put this in your ~/.zshrc (or in the same file as your prompt theme):

ZLE_RPROMPT_INDENT=0

Details

In versions of ZSH leading up to 5.0.2 a value in ZSH's C source code called rprompt_off (which set the right-margin offset) was hard-coded to 1.

But in the 5.0.5 release the developers added the ability to override this default value by setting the ZLE_RPROMPT_INDENT environment variable.

The rationale for this "indent" is because some older terminals would start scrolling if the last cell of the display had a character in it.

For versions of ZSH prior to 5.0.5

If you're on an older version of ZSH and can't update, you can still get rid of that space by doing both of the following:

  1. Trick ZSH into thinking your RPROMPT is a character shorter than it actually is using the standard invisible sequence wrapper: %{...%}
  2. Then sending a cursor-back escape sequence using terminfo: %{terminfo[cub1]}

Check out the FAQ and this message on the mailing list for more info.


I have sent a bug report to the zsh maintainers, but it seems this behavior is by design. This issue however annoyed me so much that I decided to patch and compile zsh myself as a temporary fix. If you're on OS X and use Homebrew (you should), then you can install zsh including my patch by running:

brew install https://gist.github.com/padde/7963205/raw/eaedcc557859a40db87282fc39256fccd52d0aad/zsh.rb

you will likely want to add /usr/local/bin/zsh to /etc/shells and chsh -s /usr/local/bin/zsh afterwards. Lastly, here's the raw diff for anyone who's interested:

diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index 17b78ce..f136178 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -1576,7 +1576,7 @@ zrefresh(void)
    else
        put_rpmpt = rprompth == 1 && rpromptbuf[0] &&
        !strchr(rpromptbuf, '\t') &&
-       (int)ZR_strlen(nbuf[0]) + rpromptw < winw - 1;
+       (int)ZR_strlen(nbuf[0]) + rpromptw < winw;
     } else {
 /* insert >.... on first line if there is more text before start of screen */
    ZR_memset(nbuf[0], zr_sp, lpromptw);
@@ -1631,9 +1631,9 @@ zrefresh(void)
    if (put_rpmpt && !iln && !oput_rpmpt) {
        int attrchange;

-       moveto(0, winw - 1 - rpromptw);
+       moveto(0, winw - rpromptw);
        zputs(rpromptbuf, shout);
-       vcs = winw - 1;
+       vcs = winw;
    /* reset character attributes to that set by the main prompt */
        txtchange = pmpt_attr;
        /*

Tags:

Prompt

Zsh