Usuwanie niepotrzebnego miejsca na końcu prawego monitu zsh ($ RPROMPT)

18

W Zsh zawsze po prawej stronie mojego monitu jest spacja. Próbowałem z bardzo prostym .zshrc, takim jak:

PROMPT="#"
RPROMPT="*"

Po * po prawej stronie ekranu zawsze znajduje się spacja.

Oto zrzut ekranu pokazujący problem (wybrałem miejsce w jednym z wierszy). http://i.imgur.com/cnfa2eJ.png

Dzięki.

Frozax
źródło

Odpowiedzi:

20

TL; DR

Wszystko, co musisz zrobić, to umieścić to w swoim ~/.zshrc(lub w tym samym pliku, co motyw zachęty):

ZLE_RPROMPT_INDENT=0

Detale

W wersjach ZSH prowadzących do 5.0.2 wartość kodu źródłowego ZSH o nazwie rprompt_off(która ustawia przesunięcie prawego marginesu) była na stałe zakodowana 1.

Ale w wersji 5.0.5 programiści dodali możliwość zastąpienia tej wartości domyślnej poprzez ustawienie ZLE_RPROMPT_INDENTzmiennej środowiskowej.

Uzasadnieniem dla tej „tiret” Jest tak, ponieważ niektóre starsze terminale zaczną przesuwać jeżeli ostatnia komórka wyświetlacza miała charakter w nim.

Dla wersji ZSH wcześniejszych niż 5.0.5

Jeśli korzystasz ze starszej wersji ZSH i nie możesz zaktualizować, nadal możesz pozbyć się tego miejsca, wykonując oba następujące kroki:

  1. Oszukać zsh na myśli swoją RPROMPT to postać krótszy niż jest w rzeczywistości przy użyciu standardowego opakowania niewidoczny sekwencji:%{...%}
  2. Następnie wysyłanie sekwencji ucieczki kursora za pomocą terminfo: %{terminfo[cub1]}

Sprawdź FAQ i tę wiadomość na liście mailowej, aby uzyskać więcej informacji.

Anthony Michael Cook
źródło
5
Wydaje się również, że umieszcza kursor wprowadzania jeden znak na lewo od miejsca, w którym normalnie by się znajdował. Na przykład za pomocą podpowiedzi w tym pytaniu kursor jest umieszczany na znaku krzyżyka, a nie bezpośrednio po jego prawej stronie. (Dla mnie ustawienie przesunięcia na wartość mniejszą od zera powoduje, że podpowiedzi i kursor pojawiają się w odpowiednich miejscach. Obserwowane z zsh 5.0.8 i 5.2.)
Rob Kennedy
Działa dla mnie w 5.2.
Anthony Michael Cook
5
To trochę działało dla mnie w 5.2, ale teraz mam problemy z PROMPT: ostatnia postać w PROMPT zniknęła, a przełączanie autouzupełniania wypełnia ten ostatni znak pierwszym znakiem bieżącego wejścia. Na przykład %git<Tab>przekształca się w%ggit
roboslone
Nie musisz używać sztuczek w nowszych wersjach ZSH.
Anthony Michael Cook
5
Po ustawieniu ZLE_RPROMPT_INDENT = 0 zauważyłem te same problemy z błędami rysunkowymi po lewej stronie, o których wspominają inni. Jednak prawie wszystko działa zgodnie z oczekiwaniami, jeśli użyję -1 zamiast 0, tj. ZLE_RPROMPT_INDENT = -1. Widziałem tę wskazówkę na github.com/bhilburn/powerlevel9k/issues/… . Prawie, ponieważ z -1 nigdy nie używa dolnej linii okna terminala na macOS.
Marc Liyanage
2

Wysłałem raport o błędzie do opiekunów zsh, ale wygląda na to, że takie zachowanie jest zgodne z projektem. Ten problem jednak mnie tak zirytował, że postanowiłem samodzielnie załatać i skompilować zsh jako tymczasową poprawkę. Jeśli korzystasz z systemu OS X i używasz Homebrew (powinieneś), możesz zainstalować zsh wraz z moją łatą, uruchamiając:

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

prawdopodobnie będziesz chciał dodać /usr/local/bin/zshdo /etc/shellsi chsh -s /usr/local/bin/zshpo jej zakończeniu. Na koniec, oto surowy plik różnicowy dla każdego, kto jest zainteresowany:

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
źródło
PWS (opiekun zsh) właśnie opublikował rozszerzoną łatkę , więc wcięcie RPROMPT powinno wkrótce znaleźć się w „oficjalnych” źródłach.
mpy
Dziękujemy za opublikowanie linku. Czekamy na następne wydanie!
Patrick Oscity,
1

Myślę, że biała przestrzeń po prawej jest zakodowana na stałe. Możesz jednak oszukać zshza pomocą następującego ustawienia:

RPROMPT="%{*%}"

co w zasadzie mówi, zshże gwiazda nie zajmuje znaków; z man zshmisc:

%{...%} Dołącz ciąg jako dosłowną sekwencję ucieczki. Łańcuch w nawiasach klamrowych nie powinien zmieniać pozycji kursora. (...)

Wadą jest to, że „przesuwasz” puste miejsce na koniec PROMPT:

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

Te |symbole oznaczają końcowe krawędzie ■ kursora.


Innym pomysłem byłoby zwiększenie COLUMNSo 1:

COLUMNS=$((COLUMNS + 1))

Ale trzeba wymyślić sposób, jak to zrobić tylko dla szybkiego renderowania, ale nie dla poleceń. Spowoduje to połknięcie ostatniego znaku w każdym wierszu wiersza polecenia z wieloma wierszami.

mpy
źródło
1
Dzięki. Próbowałem grać lewą% {...%}, zajmując się czasem i statusem git wyświetlanym po prawej stronie. Nie przeszkadza mi dodatkowe miejsce w PROMPT, ponieważ zazwyczaj mam jedno. Jednak jest jedna wielka wada tego rozwiązania: kiedy włączyć autouzupełnianie z języczkiem, dodatkowa przestrzeń jest usuwany i robi dziwne rzeczy :)
Frozax