Exibir itens abaixo do prompt em um prompt do shell?

21

Vamos dizer que meu prompt se parece com isso (o _ representa meu cursor)

~ % _

Existe alguma maneira de fazer isso parecer assim

~ % _
[some status]

A questão era originalmente sobre zsh, mas agora tem outras respostas.

xenoterracida
fonte
Que tal tela + buobu ?: launchpad.net/byobu e talvez kmandla.wordpress.com/2010/01/03/… para capturas de tela
Janus

Respostas:

17

As seguintes configurações parecem funcionar. O texto na segunda linha desaparece se a linha de comando ultrapassar a primeira linha. A preexecfunção apaga a segunda linha antes de executar o comando; se você quiser mantê-lo, mude para preexec () { echo; }.

terminfo_down_sc=$terminfo[cud1]$terminfo[cuu1]$terminfo[sc]$terminfo[cud1]
PS1_2='[some status]'
PS1="%{$terminfo_down_sc$PS1_2$terminfo[rc]%}%~ %# "
preexec () { print -rn -- $terminfo[el]; }

%escapes estão documentados no manual zsh ( man zshmisc).

Terminfo é uma API de acesso ao terminal. O Zsh possui um terminfomódulo que dá acesso ao banco de dados de descrição do terminal: $terminfo[$cap]é a sequência de caracteres a serem enviados para exercer a capacidade do terminal $cap, ou seja, para executar seu $capcomando. Consulte man 5 terminfo(no Linux, o número da seção pode variar em outros departamentos) para obter mais informações.

A sequência de ações é: mova o cursor uma linha para baixo ( cud1) e depois para cima ( cuu1); salve a posição do cursor ( sc); mova o cursor uma linha para baixo; impressão [some status]; restaure a posição do cursor. O bit para baixo e para cima no início é necessário apenas se o prompt estiver na linha inferior da tela. A linha preexec apaga a segunda linha ( el) para não se confundir com a saída do comando.

Se o texto na segunda linha for mais largo que o terminal, o visor poderá ficar distorcido. Use Ctrl+ Lem uma pitada para reparar.

Gilles 'SO- parar de ser mau'
fonte
5

Aqui está o bashequivalente à solução zsh de Gilles. O Bash não possui um módulo terminfo nativo, mas o tputcomando (incluído no pacote terminfo) faz a mesma coisa.

PS1_line1='\w \$ '
PS1_line2='[some status]'

if (tput cuu1 && tput sc && tput rc && tput el) >/dev/null 2>&1
then
    PS1="
\[$(tput cuu1; tput sc)\]
\[${PS1_line2}$(tput rc)\]${PS1_line1}"
    PS2="\[$(tput el)\]> "
    trap 'tput el' DEBUG
else
    PS1="$PS1_line2 :: $PS1_line1"
fi

Se o terminal não suportar um dos recursos, ele retornará ao prompt de uma linha.

A traplinha é uma maneira hacky de emular a preexecfunção do zsh . Consulte /superuser/175799/ para obter mais informações.

EDIT : Script melhorado com base nos comentários de Gilles.

Jander
fonte
@ Gilles: Obrigado pela contribuição! Eu acho que estou trabalhando melhor agora. Tentei o bash 4.1.5 no gnome-terminal e no xterm e o bash 3.2.48 no OSX Terminal.
Jander