Dividir o shell horizontalmente para mostrar ls -al e pwd

2

Eu uso o zsh como meu shell padrão no OSX. Eu gostaria que meu shell sempre tivesse uma divisão horizontal mostrando pwd e ls do diretório atual em que estou. Como faço para isso?

    
por madhukar93 23.05.2015 / 07:18

2 respostas

2

Seu caso de uso não é muito convincente. A maioria das pessoas inclui o diretório atual como parte de seu prompt; O zsh possui possibilidades de configuração de prompt extremamente ricas (incluindo avisos de múltiplas linhas, avisos para a esquerda e para a direita, etc.). Com a conclusão (que novamente no zsh é muito configurável), você pode mostrar listas de arquivos nos contextos onde você precisa deles. Dito isto, existem maneiras de conseguir o que você descreve, mas nenhuma é fácil e agradável.

Com o shell apenas

O shell está apenas no controle de sua própria entrada e saída. Quando você executa um comando, o shell não está no controle de nada. Se você quiser reservar uma parte do terminal para coisas como ls output, você precisa da cooperação do terminal. Qual é a diferença exata entre um 'terminal', um 'shell', um 'tty' e um 'console'? pode ser um plano de fundo útil.

Em alguns terminais, você pode definir uma região rolável; o que está fora da região rolável permanece no lugar. Eu sei que o xterm suporta esse recurso, não sei se outros emuladores de terminal populares fazem isso. Aqui está uma prova de conceito para exibir a saída de date , pwd e ls no terço inferior do terminal.

reset () {
  tput reset
  scrollable_lines=$((LINES*2/3))
  tput csr 0 $((scrollable_lines-1))
} 
update_status () {
  tput sc
  tput cup $((scrollable_lines+2)) 0
  tput ed
  date
  pwd
  ls -x --color=always | head -n $((LINES-scrollable_lines-3))
  tput rc
}
PROMPT_COMMAND='update_status'
reset

Algumas palavras de explicação:

  • O comando tput envia seqüências de controle obtidas via terminfo para o terminal.
  • A chamada para tput csr define a região de rolagem para as 2/3 linhas principais.
  • A função reset precisa ser executada em uma reinicialização do terminal, porque uma reinicialização do terminal redefine a região de rolagem para ser o terminal inteiro.
  • tput sc salva a posição do cursor, a ser restaurada posteriormente com tput rc .
  • tput cup move o cursor para o topo da região sem rolagem. tput ed apaga o que já está lá.
  • A função update_status é executada toda vez que bash está prestes a exibir um novo prompt.

Eu tentei isso em zsh, mas ele interage com o terminal mais do que o bash, então mesmo uma prova de conceito requer mais ajuste.

Com um multiplexador de terminal

Ambas as Tela e O Tmux pode dividir o terminal em várias sub-janelas (a tela chama essas regiões, o tmux as chama de painéis). Você pode executar um multiplexador, executar seu shell na janela superior e executá-lo em outras coisas na janela inferior.

É fácil acionar algo no shell para fazer com que as coisas sejam exibidas na janela inferior: basta redirecionar a saída para o dispositivo terminal correto. A parte complicada aqui é obter o nome do dispositivo e manter a janela inferior aberta o quanto for necessário, mas não mais.

Aqui está uma prova de conceito usando zsh e screen. Executar screen -c ~/etc/split.screenrc onde ~/etc/split.screenrc contém

escape ^\\
hardstatus off
split
focus
resize 10
screen ~/bin/bottom_tty
focus
screen zsh

Isso cria uma região inferior de 10 linhas que executa o programa ~/bin/bottom_tty e executa zsh na região superior. Em ~/bin/bottom_tty , obtenha alguns parâmetros e durma para sempre:

#!/bin/sh
cat <<EOF >~/.split-screen.$PPID.tmp
bottom_tty=$(tty)
bottom_lines=$(tput lines)
bottom_pid=$$
EOF
mv ~/.split-screen.$PPID.tmp ~/.split-screen.$PPID
while true; do sleep 999999999; done

Em .zshrc , leia as informações e configure algumas coisas:

  • Sempre que um prompt for exibido, execute refresh_bottom_tty para atualizar o conteúdo da região inferior.
  • Quando o zsh sair, mate o programa na região inferior, para que o script termine.
refresh_bottom_tty () {
  printf %s $terminfo[clear]
  date
  pwd
  ls -x --color | head -n $((bottom_lines-2))
}
precmd () {
  refresh_bottom_tty <>$bottom_tty 1>&0 2>&0
}
zshexit () {
  kill -HUP -$bottom_pid
}

while [[ ! -e ~/.split-screen.$PPID ]]; do
  sleep 1
done
. ~/.split-screen.$PPID
rm ~/.split-screen.$PPID

Wrapper de terminal dedicado

Seria possível fazer um trabalho muito melhor e mais robusto com um wrapper dedicado que entende o que você quer fazer com ele. O wrapper definiria um terminal virtual no qual o shell é executado e haveria uma interface para permitir que o shell atualize o que é exibido fora do terminal virtual.

A tela e o tmux estão realmente próximos de fornecer a funcionalidade necessária, por meio da linha de status. No entanto, ambos estão limitados a uma única linha de status. Se eles forem estendidos para suportar linhas de status de várias linhas, você poderá exibir o que deseja lá.

Como alternativa, você pode usar o módulo zpty para escrever um invólucro dedicado. Haveria então duas instâncias de zsh: uma para o wrapper, uma para executar os comandos. Conseguir isso até mesmo para uma prova de conceito é mais código do que eu gostaria de escrever nesta resposta.

    
por 26.05.2015 / 05:52
0

Eu não sei sobre showins ls output, mas o zsh tem um recurso bacana RPROMPT . Coloque isso em .zshrc e veja se ele atende às suas necessidades:

PROMPT=$'%n@%m\n%! %% '
RPROMPT='# %d'

Isso coloca o diretório de trabalho atual no lado direito do prompt para mim. Eu incluo um exemplo de PROMPT com uma nova linha, de modo que se RPROMPT não funcionar como você gostaria, você pode ver como colocar "% d" no valor de PROMPT , para que pode estar na sua própria linha.

    
por 23.05.2015 / 17:15

Tags