как отформатировать путь в приглашении zsh?

23

Я хотел бы иметь читаемый цветной путь. Например, вместо того, чтобы просто использовать% ~ для возврата, ~/path/to/fooя хотел бы отформатировать его, ~$RED/$NOCOLORpath$RED/$NOCOLORto$RED/$NOCOLORfooчтобы выделить разделители пути.

Могу ли я определить содержимое PROMPT, чтобы выражение пути переоценивалось на каждом дисплее? Что-то вроде ${${(%):-%~}//\//_some_format_expression/}явно не работает.

Или я должен взломать это дальше и заставить сбросить значение PROMPT каждый раз, когда мы меняем каталог?

Любое решение, достигающее цели форматирования пути, будет приветствоваться.

Благодарность :)

Николя Думазет
источник
если вы все еще существуете, вы можете отметить лучший ответ для этого :)
Дэн Розенстарк

Ответы:

37

ЗШ

Попробуй это:

setopt PROMPT_SUBST
PROMPT='%{$(pwd|grep --color=always /)%${#PWD}G%} %(!.%F{red}.%F{cyan})%n%f@%F{yellow}%m%f%(!.%F{red}.)%#%f '

Вот разбивка подсказки:

  • PROMPT_SUBST включает подстановку команд в командной строке (а также расширение параметров и арифметическое расширение)
  • %{...%} - escape-последовательность
  • $(pwd|grep --color=always /)- напечатать текущий каталог и выделить /- цвет будет зависеть от переменной среды $ GREP_COLORS (или ее значения по умолчанию) - полужирный красный является значением по умолчанию
  • %${#PWD}G- используйте длину в символах имени текущего каталога в качестве значения сбоя. Это заставляет оболочку учитывать это длину предыдущей последовательности символов (после " %{") вместо фактической длины строки, которая включает escape-последовательности ANSI. Это предохраняет оболочку от путаницы относительно позиции курсора относительно конца подсказки.
    - - - - - - - это конец части, которая отвечает на ваш вопрос - - - - - - -
  • %(!.%F{red}.%F{cyan}) - если это привилегированная оболочка (root), установите цвет переднего плана на красный, в противном случае - голубой
  • %n - вывести имя пользователя
  • %f - сбросить цвет переднего плана на значение по умолчанию
  • @ - буквальный знак
  • %F{yellow} - сделать цвет переднего плана желтым
  • %m - вывести имя хоста
  • %f - сбросить цвет переднего плана на значение по умолчанию
  • %(!.%F{red}.) - если это привилегированная оболочка (root), установите цвет переднего плана на красный
  • %#- вывести #для привилегированной оболочки или %для непривилегированной
  • %f - сбросить цвет переднего плана на значение по умолчанию

Я ставлю путь первым в этой подсказке для акцента, так как вопрос касается пути.

альтернативный текст

Вот версия для zsh, которая меняет цвет косой черты в зависимости от того, являетесь ли вы пользователем root (привилегированным), манипулируя этой $GREP_COLORSпеременной:

setopt PROMPT_SUBST
PROMPT='%{$(pwd|([[ $EUID == 0 ]] && GREP_COLORS="mt=01;31" grep --color=always /|| GREP_COLORS="mt=01;34" grep --color=always /))%${#PWD}G%} %(!.%F{red}.%F{cyan})%n%f@%F{yellow}%m%f%(!.%F{red}.)%#%f '

удар

Вы можете сделать аналогичное приглашение в Bash. В этом примере я сначала указал имя пользователя и хоста, а цвет слешей также меняется, когда UID равен 0. Предупреждение: это перезаписывает $PS1переменную приглашения Bash . Это не должно быть проблемой, если вы не делаете что-то особенное или не ожидаете, что поведение изменится, когда вы установите эту переменную напрямую, и это действует. Кроме того, здесь используется переменная с именем " usercolor", которая может конфликтовать с чем-то другим, хотя все это можно поместить в функцию, а переменная объявлена ​​локальной.

PROMPT_COMMAND='usercolor="\[\033[0;36m\]";[[ $EUID == 0 ]] && usercolor="\[\033[1;31m\]";PS1="$(pwd)";PS1="$usercolor\u\[\033[0m\]@\[\033[0;33m\]\h\[\033[0m\]:${PS1//\//$usercolor/\[\033[0m\]}$usercolor\\$\[\033[0m\] "'

альтернативный текст

Я воспользовался тем фактом, что в Bash нет функции «сбоя» в zsh, чтобы использовать подстановку расширения параметров для условного окрашивания слешей (вместо использования grep).

Приостановлено до дальнейшего уведомления.
источник
Назовите меня глупым, но единственная неправильная часть, которую я имел, была использованием двойных кавычек вместо одинарных кавычек в определении PROMPT. Спасибо :)
Николас Думазет
@NicDumZ, забавно, я потратил около 20 минут на эту проблему вчера в другом месте :)
Дэн Розенстарк
1
это круто (круто и круто). Спасибо ...
Дэн Розенстарк
Любая идея, как сделать это в Bash, или почему это не работает в Bash? Для меня с Bash он просто застревает в первом каталоге, в котором я запускаю свой терминал, и не обновляется при перемещении. Я просто взял $ (pwd | grep --color = always /) и вставил его в свой PS1 и получил странное поведение. Редактировать: О! Не видел раздел Bash лол.
Ибрагим
На самом деле, я пытаюсь использовать твой PS1 трюк для Bash в моем более сложном приглашении, и он не работает, мой PWD снова зависает. Но ваш фрагмент работает как есть. Какова цель PROMPT_COMMAND? Вот что у меня есть: PS1="$(pwd)"; PS1="${debian_chroot:+($debian_chroot)}\[$bldgrn\]\u@$(fgcolor $hostnamecolor)\h$(resetcolor)\[$txtrst\]:\[$bldblu\]${PS1//\//$txtred/$bldblu}\[\e[00m\]$bldred\$(parse_git_branch)\[$txtrst\] \[$undcyn\]\T \d\[$txtrst\] 95\$ "цвета, определенные в github.com/ibrahima/dotfiles/blob/master/.bashrc.d/prompt.sh
Ибрагим
4

После некоторого ухода я могу предоставить решение, которое переопределит chpwd:

doprompt() {
  local my_path=${(%):-%~}
  PROMPT="${yourstuff}${my_path//\//${PR_BOLD_RED}/${reset_color}}${otherstuff}"
}
doprompt

chpwd() {
  doprompt
  # unrelated: set window title
  [[ -t 1 ]] || return;
  print -Pn "\e]2;%n@%m: %~\a";
}
  • Есть ли способ улучшить этот код, чтобы избавиться от временной my_pathпеременной? Я не могу напрямую заменить / внутри% ~ ...
  • Любое решение, использующее динамический синтаксис, чтобы избежать вызова при каждом изменении каталога, dopromptвероятно, будет чище.
Николя Думазет
источник
4

Чистое решение Zsh:

PROMPT='%n@%m: %{$PR_BOLD_RED%}${${(%):-%~}//\//${PR_BOLD_RED}/%f}%f '
  • ${(%):-%~} это текущий путь.
  • ${xxxxx//\//${PR_BOLD_RED}/%f} заменяет каждые / в ххххх жирным красным цветом
  • и, конечно, PROMPT_SUBST должен быть включен.

Я использовал двойные кавычки в моих тестах, которые не позволяют подстановку. Все отлично работает с одинарными кавычками.

Николя Думазет
источник
Вы должны были $PR_BOLD_REDопределить в другом месте. Я должен использовать в PROMPT='%n@%m: %{%B%F{red}%}${${(%):-%~}//\//%B%F{red\}/%b%f}%b%f 'том числе очень странный выход из закрывающей фигурной скобки (только) после второй «красной».
Приостановлено до дальнейшего уведомления.
да, я использую имена Аарона Топонсе pthree.org/wp-content/uploads/2009/03/zsh_prompt, которые я нашел полезными. Кроме того, мне не нужно ничего избегать, все работает как предусмотрено.
Николас Думазет
0

Вот моя попытка (на основе NicDumZ):

setopt PROMPT_SUBST
# red, green, yellow, blue, magenta, cyan, white, black
# B (bold), K(background color), F(foreground color)

function doprompt {
# this is just the directory (%d could be %~ -- I prefer full path always)
PROMPT='%F{yellow}${${(%):-%d}//\//%F{magenta\}%B/%b%F{yellow\}}%f'
}

function chpwd() {
    doprompt
}

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

bcelary
источник