Não pode haver nenhum predisplay como o shell não está envolvido quando comandos emitem algo para o terminal ou qualquer outro arquivo.
O gancho teria que estar nos comandos executados na primeira chamada de sistema de escrita feita por qualquer processo ou encadeamento iniciado pela linha de comando para um descritor de arquivo aberto para o dispositivo tty. Ou você teria que redirecionar o stdout e o stderr do comando com algum mecanismo IPC (provavelmente teria que ser um par pseudo-tty para minimizar o impacto no comportamento do comando) e inserir o Output:
quando algo estiver recebido¹. De qualquer forma, isso seria bastante complicado e bastante intrusivo.
Agora, não é algo que eu faria, mas você poderia tentar algo como:
preexec() {
printf '%-*s' $COLUMNS "Output:"
read -sdR $'pos_before?\e[6n'
}
precmd() {
read -sdR $'pos_after?\e[6n'
[[ $pos_after != $pos_before ]] || printf '\r'
}
set +o promptsp
Ou seja, antes de executar uma saída de comando Output:
e mover o cursor para a borda direita da tela (para que a próxima coisa escrita, se houver, esteja no início da próxima linha) e registre a posição atual do cursor em $pos_before
.
E antes do próximo prompt, consulte novamente a posição do cursor e, se ele não foi movido, mova o cursor de volta para o início da linha para que o próximo prompt substitua o Output:
. Desabilitamos promptsp
, pois isso interfere nisso.
¹Esta abordagem baseada em pty poderia ser implementada com expect
, por exemplo:
#! /usr/bin/expect -f
set x 0
set timeout -1
stty raw -echo
log_user 0
spawn -noecho zsh
# tell zsh to send a special sequence before the prompt (precmd)
# and a different one before each command (preexec)
send {precmd() printf ""; preexec() printf "";set +o promptsp}
send "\r"
# wait for the second prompt
expect ""
# set our x flag when the preexec string has been output and reset
# it upon precmd. write "Output:" if some character is received while
# the flag is up.
expect {
-re "^" {
set x 1; exp_continue
}
-re "^" {
set x 0; exp_continue
}
-re "^.\[^\]*" {
if {$x} {send_user "Output:\n"; set x 0}
send_user -- "$expect_out(buffer)"
exp_continue
}
-i $user_spawn_id -re .+ {
send -- $expect_out(buffer); exp_continue
}
}