Удаление ненужного пробела в конце правой подсказки zsh ($ RPROMPT)

18

В zsh справа от моей правой подсказки всегда есть пробел. Я попробовал с очень простым .zshrc, таким как:

PROMPT="#"
RPROMPT="*"

Всегда есть пробел после * в правой части экрана.

Вот скриншот, показывающий проблему (я выбрал место на одной из строк). http://i.imgur.com/cnfa2eJ.png

Благодарю.

Frozax
источник

Ответы:

20

TL; DR

Все, что вам нужно сделать, это поместить это в свой файл ~/.zshrc(или в тот же файл, что и тема приглашения):

ZLE_RPROMPT_INDENT=0

Детали

В версиях ZSH, ведущих до 5.0.2, значение в исходном коде C языка ZSH rprompt_off(которое устанавливает смещение правого поля) было жестко запрограммировано 1.

Но в версии 5.0.5 разработчики добавили возможность переопределить это значение по умолчанию, установив ZLE_RPROMPT_INDENTпеременную среды.

Обоснование для этого «отступа» потому , что некоторые старые терминалы начнут скроллинг , если последняя ячейка дисплея имела характер в нем.

Для версий ZSH до 5.0.5

Если вы используете старую версию ZSH и не можете обновить ее, вы все равно можете избавиться от этого места, выполнив оба следующих действия:

  1. Trick ЗШ, думая , ваш RPROMPT является характер короче , чем на самом деле использует стандартную невидимая последовательность обертку:%{...%}
  2. Затем отправляем escape-последовательность курсора назад с помощью terminfo: %{terminfo[cub1]}

Проверьте FAQ и это сообщение в списке рассылки для получения дополнительной информации.

Энтони Майкл Кук
источник
5
Это также, кажется, помещает курсор ввода на один символ слева от того места, где он обычно находится. Например, используя подсказки в этом вопросе, курсор помещается на хэш-метку, а не сразу справа. (Для меня установка смещения на значение, меньшее нуля, заставляет подсказки и курсор появляться в правильных местах. Наблюдается с помощью zsh 5.0.8 и 5.2.)
Роб Кеннеди
У меня работает в 5.2.
Энтони Майкл Кук
5
Это вроде как сработало для меня в 5.2, но теперь у меня есть проблемы с PROMPT: последний символ в PROMPT исчез, и переключение автозаполнения заполняет этот последний символ первым символом текущего ввода. Например %git<Tab>трансформируется в%ggit
roboslone
Вам не нужно использовать приемы для новых версий ZSH.
Энтони Майкл Кук
5
После установки ZLE_RPROMPT_INDENT = 0 я заметил те же проблемы с рисованием в левой подсказке, о которых некоторые другие упоминали выше. Однако почти все работает как положено, если я использую -1 вместо 0, то есть ZLE_RPROMPT_INDENT = -1. Я видел этот совет на github.com/bhilburn/powerlevel9k/issues/… . Почти, потому что с -1 он никогда не использует нижнюю строку окна терминала в macOS.
Марк
2

Я отправил отчет об ошибке сопровождающим zsh, но, похоже, это поведение разработано. Эта проблема, однако, настолько раздражала меня, что я решил исправить и скомпилировать zsh как временное исправление. Если вы используете OS X и используете Homebrew (вам следует), вы можете установить zsh, включая мой патч, запустив:

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

Вы, вероятно , захотите добавить /usr/local/bin/zshк /etc/shellsи chsh -s /usr/local/bin/zshпосле этого. Наконец, вот сырье для всех, кто заинтересован:

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;
        /*
Патрик Осцити
источник
PWS (сопровождающий zsh) только что опубликовал расширенный патч , поэтому отступы RPROMPT должны появиться в «официальных» источниках в ближайшее время.
mpy
Спасибо за размещение ссылки. С нетерпением ждем следующего релиза!
Патрик Осци
1

Я думаю, что пустое пространство справа жестко запрограммировано. Но вы можете обмануть zshсо следующими настройками:

RPROMPT="%{*%}"

что в принципе говорит zshо том, что звезда не занимает никаких символов; от man zshmisc:

%{...%} Включите строку как буквальную escape-последовательность. Строка в фигурных скобках не должна менять позицию курсора. (...)

Недостаток в том, что вы «сдвигаете» пробел до конца PROMPT:

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

Эти |символы обозначают концевые ребра, ■ курсор.


Другая идея заключается в увеличении COLUMNSна 1:

COLUMNS=$((COLUMNS + 1))

Но нужно придумать, как это сделать только для быстрого рендеринга, но не для команд. И это поглотит последний символ в каждой строке многострочной командной строки.

МРУ
источник
1
Благодарю. Я попытался поиграть с трюком% {...%}, имея в виду мое время и статус мерзавца, показанные справа. Я не против дополнительного места на PROMPT, потому что у меня обычно есть один. Однако у этого решения есть один большой недостаток: когда я активирую автозаполнение с помощью TAB, лишнее пространство удаляется, и это делает странные вещи :)
Frozax