como formatar o caminho em um prompt zsh?

23

Eu adoraria ter um caminho colorido legível. Por exemplo, em vez de simplesmente usar% ~ para retornar ~/path/to/foo, gostaria de formatá-lo ~$RED/$NOCOLORpath$RED/$NOCOLORto$RED/$NOCOLORfoopara destacar os separadores de caminho.

Posso definir o conteúdo do PROMPT para que a expressão do caminho seja reavaliada em cada exibição? Algo como ${${(%):-%~}//\//_some_format_expression/}obviamente não funciona.

Ou devo cortar isso ainda mais e forçar o valor PROMPT a ser redefinido toda vez que mudarmos um diretório?

Qualquer solução que atinja o objetivo de formatação de caminho seria bem-vinda.

Obrigado :)

Nicolas Dumazet
fonte
se você ainda existem você pode querer marcar a melhor resposta para isso :)
Dan Rosenstark

Respostas:

36

zsh

Tente o seguinte:

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

Aqui está um detalhamento do prompt:

  • PROMPT_SUBST ativa a substituição de comandos no prompt (e expansão de parâmetros e expansão aritmética)
  • %{...%} - uma sequência de escape
  • $(pwd|grep --color=always /)- imprima o diretório atual e realce /- a cor dependerá da variável de ambiente $ GREP_COLORS (ou seu valor padrão) - negrito é o padrão
  • %${#PWD}G- use o comprimento em caracteres do nome do diretório atual como um valor de falha. Isso faz com que o shell considere esse o comprimento da sequência de caracteres anterior (após o " %{") em vez do comprimento real da cadeia de caracteres que inclui as seqüências de escape ANSI. Isso evita que o shell fique confuso sobre a posição do cursor em relação ao final do prompt.
    - - - - - - - este é o fim da parte que responde à sua pergunta - - - - - - -
  • %(!.%F{red}.%F{cyan}) - se esse for um shell privilegiado (raiz), defina a cor do primeiro plano como vermelho, caso contrário, ciano
  • %n - gera o nome de usuário
  • %f - redefinir a cor do primeiro plano para o padrão
  • @ - um literal no sinal
  • %F{yellow} - deixe a cor do primeiro plano amarela
  • %m - gera o nome do host
  • %f - redefinir a cor do primeiro plano para o padrão
  • %(!.%F{red}.) - se esse for um shell privilegiado (raiz), defina a cor do primeiro plano como vermelho
  • %#- produza a #para um shell privilegiado ou %para um não privilegiado
  • %f - redefinir a cor do primeiro plano para o padrão

Coloquei o caminho em primeiro lugar neste prompt de ênfase, pois a pergunta diz respeito ao caminho.

texto alternativo

Aqui está uma versão do zsh que muda a cor da barra dependendo se você é root (privilegiado) manipulando a $GREP_COLORSvariável:

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 '

Bater

Você pode fazer um prompt semelhante no Bash. Neste exemplo, coloquei o usuário e o nome do host em primeiro lugar e a cor das barras também muda quando o UID é 0. Aviso: isso substitui a $PS1variável de prompt do Bash . Isso não deve ser um problema, a menos que você esteja fazendo algo especial ou espere que o comportamento mude quando você definir essa variável diretamente e isso estiver em vigor. Além disso, isso usa uma variável chamada " usercolor" que pode colidir com outra coisa, embora tudo possa ser colocado em uma função e a variável declarada local.

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\] "'

texto alternativo

Aproveitei o fato de o Bash não ter o recurso "falha" do zsh para usar a substituição de expansão de parâmetro para colorir condicionalmente as barras (em vez de usar grep).

Pausado até novo aviso.
fonte
me chame de idiota, mas a única parte errada que tive foi o uso de aspas duplas em vez de aspas simples na definição PROMPT. Obrigado :)
Nicolas Dumazet 30/10/09
@NicDumZ, engraçado, eu gasto cerca de 20 minutos em que outro lugar problema ontem :)
Dan Rosenstark
1
isso é massivamente (nerd e) legal. Obrigado ...
Dan Rosenstark
Alguma idéia de como fazer isso no Bash ou por que não funciona no Bash? Para mim, com o Bash, ele fica preso no primeiro diretório em que inicio o terminal e não é atualizado quando me movo. Eu peguei o $ (pwd | grep --color = sempre /) e coloquei no meu PS1 e tive um comportamento estranho. Editar: OH! Não viu a seção Bash lol.
Ibrahim
Na verdade, estou tentando usar o truque do PS1 para o Bash no meu prompt mais complexo e não está funcionando, meu PWD fica preso novamente. Mas seu snippet funciona como está. Qual é o objetivo de PROMPT_COMMAND? Isto é o que eu tenho: 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\$ "cores definidas em github.com/ibrahima/dotfiles/blob/master/.bashrc.d/prompt.sh
Ibrahim
4

Depois de alguma solução, posso fornecer uma solução que substitua 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";
}
  • Existe uma maneira de melhorar esse código para se livrar do my_pathvar temporário ? Não consigo substituir diretamente o / inside% ~ ...
  • Qualquer solução que utilize uma sintaxe dinâmica para evitar a chamada em cada alteração de diretório doprompté provavelmente mais limpa.
Nicolas Dumazet
fonte
4

Uma solução zsh pura:

PROMPT='%n@%m: %{$PR_BOLD_RED%}${${(%):-%~}//\//${PR_BOLD_RED}/%f}%f '
  • ${(%):-%~} é o caminho atual.
  • ${xxxxx//\//${PR_BOLD_RED}/%f} substitui todos / em xxxxx por um corajoso vermelho
  • e é claro que PROMPT_SUBST precisa estar ativado.

Eu usava aspas duplas nos meus testes, o que não permite a substituição. Tudo funciona bem com aspas simples.

Nicolas Dumazet
fonte
Você deve ter $PR_BOLD_REDdefinido em outro lugar. Eu tenho que usar, PROMPT='%n@%m: %{%B%F{red}%}${${(%):-%~}//\//%B%F{red\}/%b%f}%b%f 'incluindo a fuga muito estranha da chave de fechamento (apenas) após o segundo "vermelho".
Pausado até novo aviso.
sim, eu uso os nomes de Aaron Toponce pthree.org/wp-content/uploads/2009/03/zsh_prompt que achei úteis. Além disso, não preciso escapar de nada, funciona como previsto.
Nicolas Dumazet 01/11/2009
0

Aqui está minha tentativa (baseada no 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
}

A diferença é que estou usando o caminho colorido, por isso preciso retornar à minha cor original para o caminho depois que a barra for colorida. No meu caso, o caminho é normalmente amarelo, e a barra fica colorida com magenta, depois retorna para amarelo. Também prefiro usar sequências% F% f, pois elas parecem muito mais legíveis para mim.

bcelary
fonte