Removendo o espaço inútil no final do prompt direito do zsh ($ RPROMPT)

17

No zsh, sempre há um caractere de espaço à direita do prompt correto. Eu tentei com um .zshrc muito simples, como:

PROMPT="#"
RPROMPT="*"

Sempre existe um espaço após o * à direita da tela.

Aqui está uma captura de tela mostrando o problema (selecionei o espaço em uma das linhas). http://i.imgur.com/cnfa2eJ.png

Obrigado.

Frozax
fonte

Respostas:

19

TL; DR

Tudo o que você precisa fazer é colocar isso no seu ~/.zshrc(ou no mesmo arquivo que o seu tema de prompt):

ZLE_RPROMPT_INDENT=0

Detalhes

Nas versões do ZSH anteriores à 5.0.2, um valor no código-fonte C do ZSH chamado rprompt_off(que definia o deslocamento da margem direita) era codificado para 1.

Mas na versão 5.0.5, os desenvolvedores acrescentaram a capacidade de substituir esse valor padrão, definindo a ZLE_RPROMPT_INDENTvariável de ambiente.

A justificativa para esse "recuo" é porque alguns terminais mais antigos começariam a rolar se a última célula da tela tivesse um caractere.

Para versões do ZSH anteriores à 5.0.5

Se você estiver em uma versão mais antiga do ZSH e não puder atualizar, ainda poderá se livrar desse espaço fazendo o seguinte:

  1. Engane o ZSH pensando que seu RPROMPT é um caractere mais curto do que realmente está usando o wrapper de sequência invisível padrão:%{...%}
  2. Em seguida, enviando uma sequência de escape do cursor para trás usando terminfo: %{terminfo[cub1]}

Confira as perguntas frequentes e esta mensagem na lista de discussão para obter mais informações.

Anthony Michael Cook
fonte
5
Isso também parece colocar o cursor de entrada com um caractere à esquerda de onde normalmente estaria. Usando os prompts desta pergunta, por exemplo, o cursor é colocado na marca de hash, e não imediatamente à sua direita. (Para mim, estabelecendo o deslocamento para um valor inferior a zero faz com que os prompts e cursor aparecem nos lugares corretos Observado com zsh 5.0.8 e 5.2..)
Rob Kennedy
Funciona para mim no 5.2.
Anthony Michael Cook
5
Meio que funcionou para mim na versão 5.2, mas agora tenho problemas com o PROMPT: o último caractere do PROMPT desapareceu e o preenchimento automático alternado preenche esse último caractere com o primeiro caractere da entrada atual. Por exemplo, %git<Tab>transforma-se em%ggit
roboslone 16/07
Você não precisa usar os truques para versões mais recentes do ZSH.
Anthony Michael Cook
5
Depois de definir ZLE_RPROMPT_INDENT = 0, notei os mesmos problemas de falha de desenho no prompt do lado esquerdo que alguns outros mencionam acima. No entanto, quase tudo funciona como esperado se eu usar -1 em vez de 0, ou seja, ZLE_RPROMPT_INDENT = -1. Eu vi essa dica em github.com/bhilburn/powerlevel9k/issues/… . Quase, porque com -1 ele nunca usa a linha inferior de uma janela de terminal no macOS.
Marc Liyanage
2

Enviei um relatório de bug para os mantenedores do zsh, mas parece que esse comportamento ocorre por design. Esse problema, no entanto, me incomodou tanto que decidi corrigir e compilar o zsh como uma correção temporária. Se você estiver no OS X e usar o Homebrew (você deveria), poderá instalar o zsh, incluindo o meu patch, executando:

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

você provavelmente vai querer adicionar /usr/local/bin/zsha /etc/shellse chsh -s /usr/local/bin/zshdepois. Por fim, aqui está o diff bruto para quem estiver interessado:

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;
        /*
Patrick Oscity
fonte
O PWS (mantenedor do zsh) acabou de publicar um patch estendido , portanto o recuo do RPROMPT deve estar nas fontes `` oficiais '' em breve.
mpy
Obrigado por postar o link. Ansioso para o próximo lançamento!
Patrick Oscity
1

Eu acho que o espaço em branco à direita é codificado. Mas você pode enganar zshcom a seguinte configuração:

RPROMPT="%{*%}"

que em princípio diz zshque a estrela não ocupa caracteres; de man zshmisc:

%{...%} Inclua uma sequência como uma sequência de escape literal. A cadeia de caracteres entre chaves não deve alterar a posição do cursor. (...)

A desvantagem é que você "desloca" o espaço em branco para o final de PROMPT:

| PROMPT = "#" |
| RPROMPT = "% {*%}" |
| # ■ * |

Os |símbolos indicam as bordas do terminal, ■ o cursor.


Outra idéia seria aumentar COLUMNSem 1:

COLUMNS=$((COLUMNS + 1))

Mas é preciso pensar em uma maneira de fazer isso apenas para a renderização imediata, mas não para os comandos. E isso engolirá o último caractere em cada linha em uma linha de comando com várias linhas.

mpy
fonte
11
Obrigado. Tentei jogar com o truque% {...%}, lidando com meu tempo e status de git exibidos à direita. Não me importo com o espaço extra no PROMPT, porque normalmente tenho um. No entanto, existe uma grande desvantagem com esta solução: quando eu ativar auto-completar com TAB, o espaço extra é removido e que está fazendo coisas estranhas :)
Frozax