Como iniciar o XTerm com o prompt na parte inferior?

10

Ao iniciar o XTerm, o prompt começa na primeira linha do terminal. Ao executar comandos, o prompt desce até chegar ao final e, a partir de então, ele permanece lá (nem mesmo Shift - Page Down ou o mouse pode mudar isso). Em vez de ter o início da vida útil do terminal ser "especial" , o aviso deve estar sempre na parte inferior do terminal. Por favor, note que eu tenho um prompt de multi-linha .

Obviamente, deve funcionar como antes (redimensionável, rolável, sem novas linhas desnecessárias na saída e nenhuma saída desaparecendo misteriosamente), portanto, PROMPT_COMMAND='echo;echo;...' ou similar não é uma opção. A solução ideal não deve ser específica do shell.

Editar: A solução atual , ao trabalhar em casos simples, tem um alguns problemas:

  • É específico do Bash . Uma solução ideal deve ser portável para outras camadas.
  • A falha se outros processos modificarem PS1 . Um exemplo é o virtualenv, que adiciona (virtualenv) no início de PS1 , que então sempre desaparece logo acima da dobra.
  • Ctrl - l agora remove a última página do histórico.

Existe uma maneira de evitar esses problemas, com falta de bifurcação no XTerm?

    
por l0b0 01.09.2014 / 09:30

3 respostas

9

Se estiver usando bash , o seguinte deve fazer o seguinte:

TOLASTLINE=$(tput cup "$LINES")
PS1="\[$TOLASTLINE\]$PS1"

Ou (menos eficiente, pois executa um comando tput antes de cada prompt, mas funciona depois que a janela do terminal foi redimensionada):

PS1='\[$(tput cup "$LINES")\]'$PS1

Para evitar que tput altere o código de saída, você pode salvá-lo e redefini-lo explicitamente:

PS1='\[$(retval=$?;tput cup "$LINES";exit $retval)\]'$PS1

Observe que a variável retval é local; isso não afeta nenhuma variável retval que você possa ter definido no shell.

Como a maioria dos terminais cup capacity é o mesmo \e[y;xH , você também pode codificá-lo:

PS1='\[\e[$LINES;1H\]'$PS1

Se você quiser que seja seguro contra a reinicialização posterior do PS1, você também pode utilizar a variável PROMPT_COMMAND . Se definido, ele é executado como o comando antes de ser emitido o prompt. Então, o efeito também pode ser alcançado por

PROMPT_COMMAND='(retval=$?;tput cup "$LINES";exit $retval)'

É claro que, embora a redefinição de PS1 não afete isso, algum outro software também pode alterar PROMPT_COMMAND .

    
por 01.09.2014 / 11:41
2

As respostas que usam $LINES são desnecessariamente não portáteis. Como feito em resize , você pode simplesmente perguntar xterm para definir a posição para um número de linha arbitrariamente grande, por exemplo,

tput cup 9999 0

(supondo que você tenha uma janela menor que 10 mil linhas, desconsiderando scrollback ).

Como a string não será alterada como efeito colateral do redimensionamento da janela, você poderá calcular isso uma vez e colá-la na string de prompt como uma constante, por exemplo,

TPUT_END=$(tput cup 9999 0)

e mais tarde

PS1="${TPUT_END} myprompt: "

de acordo com suas preferências.

Quanto a outros processos que modificam PS1 : você terá que recomputar PS1 após essas alterações para garantir a aparência desejada. Mas não há detalhes suficientes na questão para apontar onde para fazer as alterações.

E finalmente: o comportamento da conclusão da tabulação não combina com esse tipo de mudança, devido às suposições do bash.

    
por 28.07.2016 / 11:33
1

Como uma pequena simplificação para a resposta anterior, achei mais fácil apenas executar:

tput cup $LINES

no início de .bashrc ou .zshrc . Apenas faz o trabalho.

Prós:

  • só imprime uma vez, quando você inicia seu shell

Contras:

  • ao limpar a tela com ^ L, ele não imprime e o aliasing clear to clear; tput ... não ajuda;
  • O prompt
  • é movido para outro lugar quando o terminal é redimensionado
por 04.12.2014 / 11:39