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

22790
Nicolas Dumazet

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

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

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

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

Спасибо :)

21
если вы все еще существуете, вы можете выбрать лучший ответ для этого :) Dan Rosenstark 14 лет назад 0

4 ответа на вопрос

33
Dennis Williamson

ЗШ

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

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

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

  • PROMPT_SUBST включает подстановку команд в приглашении (и расширение параметров и арифметическое расширение)
  • %{...%} - escape-последовательность
  • $(pwd|grep --color=always /)- напечатать текущий каталог и выделить /- цвет будет зависеть от переменной среды $ GREP_COLORS (или ее значения по умолчанию) - полужирный красный является значением по умолчанию
  • %${#PWD}G- используйте длину в символах имени текущего каталога в качестве значения сбоя. Это заставляет оболочку учитывать это длину предыдущей последовательности символов (после " %{") вместо фактической длины строки, которая включает escape-последовательности ANSI. Это предохраняет оболочку от путаницы относительно положения курсора относительно конца подсказки.
    - - - - - - - это конец части, которая отвечает на ваш вопрос - - - - - - -
  • %(!.%F.%F) - если это привилегированная оболочка (root), установите цвет переднего плана на красный, в противном случае - голубой
  • %n - вывести имя пользователя
  • %f - сбросить цвет переднего плана на значение по умолчанию
  • @ - буквальный знак
  • %F - сделать цвет переднего плана желтым
  • %m - вывести имя хоста
  • %f - сбросить цвет переднего плана на значение по умолчанию
  • %(!.%F.) - если это привилегированная оболочка (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.%F)%n%f@%F%m%f%(!.%F.)%#%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\]:$$usercolor\\$\[\033[0m\] "' 

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

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

Назовите меня глупым, но единственная неправильная часть, которую я имел, была использованием двойных кавычек вместо одинарных кавычек в определении PROMPT. Спасибо :) Nicolas Dumazet 15 лет назад 0
@NicDumZ, забавно, я потратил около 20 минут на эту проблему вчера в другом месте :) Dan Rosenstark 14 лет назад 0
это круто (круто и круто). Спасибо... Dan Rosenstark 14 лет назад 1
Любая идея, как сделать это в Bash, или почему это не работает в Bash? Для меня с Bash он просто застревает в первом каталоге, в котором я запускаю свой терминал, и не обновляется, когда я перемещаюсь. Я просто взял $ (pwd | grep --color = always /) и вставил его в свой PS1 и получил странное поведение. Редактировать: О! Не видел раздел Bash лол. Ibrahim 11 лет назад 0
На самом деле, я пытаюсь использовать твой PS1 трюк для Bash в моем более сложном приглашении, и он не работает, мой PWD снова зависает. Но ваш фрагмент работает как есть. Какова цель PROMPT_COMMAND? Вот что у меня есть: `PS1 =" $ (pwd) "; PS1 = "$ \ [$ bldgrn \] \ u @ $ (fgcolor $ hostnamecolor) \ h $ (resetcolor) \ [$ txtrst \]: \ [$ bldblu \] $ \ [\ e [00m \] $ bldred \ $ (parse_git_branch) \ [$ txtrst \] \ [$ undcyn \] \ T \ d \ [$ txtrst \] 95 \ $ "" цвета определены в https://github.com/ibrahima/dotfiles/blob/master/.bashrc.d/prompt.sh Ibrahim 11 лет назад 0
ОЙ! Теперь я это вижу. Все это в PROMPT_COMMAND, поэтому каждый раз он запускается повторно. Отлично работает сейчас. Хотя я не понимаю, что в моем приглашении была вызвана функция parse_git_branch, которая прекрасно обновляется, поэтому я не понимаю, почему не могу вставить функцию для замены строки для PWD. Ibrahim 11 лет назад 0
@Ibrahim: я считаю, что это имеет отношение к * когда * вызывается функция. `PROMPT_COMMAND` достаточно рано, а` PS1` - слишком поздно. Dennis Williamson 11 лет назад 0
Это было именно то, что я искал. Спасибо! lohiaguitar91 10 лет назад 0
Почему бы не использовать `$ PWD` и сохранить` fork`? Tom Hale 6 лет назад 0
@ TomHale: я пишу в `grep`, поэтому, если бы я использовал переменную, мне все равно пришлось бы раскошелиться на` echo`. Оба `pwd` и` echo` являются встроенными. Dennis Williamson 6 лет назад 0
3
Nicolas Dumazet

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

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

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

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

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

Вы должны иметь `$ PR_BOLD_RED`, определенный в другом месте. Я должен использовать `PROMPT = '% n @% m:% {% B% F %} $ {$ {(%): -% ~} // \ //% B% F /% b% f}% b% f '`, включая ** очень странное ** экранирование закрывающей фигурной скобки (только) после второго" красного ". Dennis Williamson 15 лет назад 0
да, я использую имена Аарона Топонсе http://pthree.org/wp-content/uploads/2009/03/zsh_prompt, которые я нашел полезными. Кроме того, мне не нужно ничего избегать, это работает как предусмотрено. Nicolas Dumazet 15 лет назад 0
0
bcelary

Вот моя попытка (на основе 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${${(%):-%d}//\//%F%B/%b%F}%f' }  function chpwd() { doprompt } 

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