Como desenhar uma linha entre comandos no shell zsh

6

Alguém sabe como desenhar linhas entre os comandos em zsh?

Aqui está um exemplo com o MobaXterm:

    
por user52441 27.11.2014 / 16:13

2 respostas

13

Para estender seu prompt PS1 atual por uma linha horizontal anterior, você pode usar um dos seguintes métodos. O princípio básico é o mesmo, mas o que funciona melhor depende do seu emulador de terminal, configuração do local e configurações de fonte.

Imprima um grupo de menos ( - ) ou sublinhado ( _ ) caracteres

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

Explicação

  • A opção promptsubst permite a substituição de parâmetros no prompt toda vez que o prompt é desenhado, neste caso COLUMNS .
  • O sinalizador de expansão de parâmetro r:$COLUMNS::_: preenche o lado direito do parâmetro com sublinhados (dados entre os dois últimos : : ) até que uma largura de $COLUMNS seja atingida. Como neste caso nenhum parâmetro é dado, somente o preenchimento é impresso.
  • O preenchimento ocupa toda a largura do terminal, o PS1 original é automaticamente encapsulado na próxima linha. Portanto, não há necessidade de adicionar uma nova linha extra. Isso também é importante, pois novas linhas explícitas podem, em alguns casos, levar à solicitação de sobrescrever a (s) última (s) linha (s) da saída. (No meu caso, isso aconteceu quando o texto do prompt antes da nova linha explícita era exatamente o tamanho do terminal.)

Isso funciona em todos os emuladores de terminal (ou console), todos os locais e todas as fontes. Mas pode não parecer tão bom: pelo menos com minuses pois haverá lacunas entre eles ( ---- ), com undercores isso depende da fonte. Os outros métodos usam maneiras diferentes de construir isso.

Underline com zsh Prompt Escapes para efeitos visuais

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

Explicação:

  • Tudo entre %U e %u está sublinhado.
  • espaços de impressão (que serão sublinhados) em vez de sublinhados

Isso deve funcionar com a maioria dos emuladores de terminal, locales e fontes, pois ele apenas usa sublinhado. Uma possível desvantagem é que a linha horizontal não será centralizada, mas muito baixa na linha de saída, logo acima da próxima linha do prompt.

Desenho de linha (também conhecido como desenho de caixa) usando um conjunto de caracteres alternativo

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

Explicação:

  • %{...%} diz a zsh para esperar apenas os códigos de escape que realmente não movem o cursor
  • \e(0 muda para o conjunto de caracteres alternativo
  • q mapeia para uma linha horizontal no conjunto de caracteres alternativo
  • \e(B volta para o conjunto de caracteres normal

Isso também deve funcionar com a maioria dos emuladores de terminal (mas provavelmente não consola), locales e fontes. A espessura da linha parece variar entre fontes e até mesmo emuladores de terminal usando a mesma fonte (na minha máquina com a fonte Terminus o urxvt imprime uma linha fina, enquanto o roxterm imprime uma linha muito grossa).

Desenho de caixa usando caracteres Unicode

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

Explicação

  • use o caractere Unicode U + 2500 ("Box Drawing Light Horizontal", ) para preenchimento.

Isso obviamente requer que o emulador de terminal ofereça suporte a caracteres Unicode, uma fonte que tenha o caractere necessário e um código do idioma UTF-8. Mas também fornece alguns estilos de linha para escolher, como espessura ( ) ou linhas duplas ( ). (consulte a tabela de códigos oficial do Unicode Consortium para saber mais)

    
por 28.11.2014 / 17:08
1

Eu acho que a linha é codificada no prompt e percebida através do prompt de sublinhado escape %U :

PS1="%U                         %u
%~ "

em que %~ é o seu prompt usual (verifique com print $PS1 ):

Maiscomplicadoétornaralinhatãoamplaquantooseuterminal.Onúmerodecaractereséarmazenadoem$COLUMNS,portanto,construímosumacadeiadeumnúmeroapropriadodeespaçosembranco,cercadospor%U/%u:

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

Como queremos atualizar o comprimento se o tamanho for alterado, redefinimos o prompt toda vez antes de ele ser redesenhado, o que pode ser feito colocando o código na função precmd() :

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

Et voilà:

    
por 27.11.2014 / 22:33

Tags