6

Кто-нибудь знает, как рисовать линии между командами в Zsh?

Вот пример с MobaXterm:

2 ответа2

13

Чтобы расширить текущее приглашение PS1 предыдущей горизонтальной линией, вы можете использовать один из следующих методов. Основной принцип тот же, но тот, который работает лучше всего, зависит от вашего эмулятора терминала, настроек локали и шрифтов.

Выведите несколько символов минус (-) или подчеркивания (_)

setopt promptsubst
PS1=$'${(r:$COLUMNS::_:)}'$PS1

объяснение

  • Опция promptsubst включает подстановку параметров внутри подсказки каждый раз, когда подсказка рисуется, в данном случае COLUMNS .
  • Флаг расширения параметра r:$COLUMNS::_: дополняет правую часть параметра символами подчеркивания (заданными между двумя последними : : :) до достижения ширины $COLUMNS . Поскольку в этом случае параметр не указан, печатается только отступ.
  • Заполнение занимает всю ширину терминала, оригинальный PS1 автоматически переносится на следующую строку. Таким образом, нет необходимости добавлять дополнительный перевод строки. Это также важно, поскольку явные переводы строки могут в некоторых случаях приводить к тому, что приглашение перезаписывает последнюю строку (строки) вывода. (В моем случае это произошло, когда текст подсказки перед явным переводом строки был ровно столько же, сколько был широкий терминал.)

Это работает на каждом эмуляторе терминала (или консоли), каждой локали и каждом шрифте. Но это может выглядеть не очень хорошо: по крайней мере, с минусами, поскольку между ними будут пробелы (----), с подчеркиванием это зависит от шрифта. Другие методы используют разные способы, чтобы основываться на этом.


Подчеркните с помощью zsh Prompt Escape для визуальных эффектов

setopt promptsubst
PS1=$'%U${(r:$COLUMNS:: :)}%u'$PS1

Объяснение:

  • Все между %U и %u подчеркнуто.
  • печатать пробелы (которые будут подчеркнуты) вместо подчеркивания

Это должно работать с большинством терминальных эмуляторов, локалей и шрифтов, так как оно использует только подчеркивание. Возможный недостаток заключается в том, что горизонтальная линия будет находиться не по центру, а очень низко на выходной линии, чуть выше следующей строки приглашения.


Рисование линий (или Box-Drawing) с использованием альтернативного набора символов

setopt promptsubst
PS1=$'%{\e(0%}${(r:$COLUMNS::q:)}%{\e(B%}'$PS1

Объяснение:

  • %{...%} говорит Zsh ожидать только escape-коды, которые фактически не перемещают курсор
  • \e(0 переключается на альтернативный набор символов
  • q отображается на горизонтальную линию в альтернативном наборе символов
  • \e(B переключается обратно на обычный набор символов

Это также должно работать с большинством терминальных эмуляторов (но, вероятно, не консольных), локалями и шрифтами. Толщина линии, кажется, варьируется между шрифтами и даже терминальными эмуляторами, использующими один и тот же шрифт (на моей машине со шрифтом Terminus urxvt печатает тонкую линию, а roxterm печатает очень толстую линию).


Рисование рамок с использованием символов Юникода

setopt promptsubst
PS1=$'${(r:$COLUMNS::\u2500:)}'$PS1

объяснение

  • используйте символ Unicode U+2500 ("Box Drawing Light Horizontal", ) для заполнения.

Это, очевидно, требует, чтобы эмулятор терминала поддерживал символы Unicode, шрифт, который имел требуемый символ, и локаль UTF-8. Но он также предоставляет несколько стилей линии на выбор, как толстый или двойные линии (см. Официальную таблицу кодов Консорциума Unicode для получения дополнительной информации)

1

Я думаю, что строка закодирована в подсказке и реализована через escape-строку подсказки подчеркивания %U:

PS1="%U                         %u
%~ "

где %~ - ваше обычное приглашение (проверьте с помощью print $PS1):

Более сложно сделать линию такой же широкой, как ваш терминал. Количество символов хранится в $COLUMNS , поэтому мы создаем строку с соответствующим количеством пробелов, окруженную %U/%u:

drawline=""
for i in {1..$COLUMNS}; drawline=" $drawline"
drawline="%U${drawline}%u"

Поскольку мы хотим обновить длину, если размер изменен, мы переопределяем приглашение каждый раз перед его перерисовкой, чего можно добиться, поместив код в precmd() :

precmd() {
   drawline=""
   for i in {1..$COLUMNS}; drawline=" $drawline"
   drawline="%U${drawline}%u"
   PS1="${drawline}
%~ "
}

И вуаля:

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .