Как нарисовать линию между командами в оболочке zsh
Кто-нибудь знает, как рисовать линии между командами в Zsh?
Вот пример с MobaXterm:
2 ответа
Для того, чтобы продлить ваш текущий 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 для получения дополнительной информации)
Я думаю, что строка закодирована в подсказку и реализована через подчеркивание подсказки %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}
%~ "
}
И вуаля: