Retomar terminal Zsh (OS X Lion)

17

O OS X Lion possui o recurso "Continuar", ou seja, quando você reabre um aplicativo, ele restaura todas as janelas e seu conteúdo. Isso funciona para o Terminal também. Mas se você usar o Zsh em vez do Bash, ele não restaurará o diretório aberto. Como posso consertar isso?

Simon Perepelitsa
fonte
Relacionado às respostas abaixo: tornar o terminal.app ciente do diretório também é útil para abrir novos terminais no mesmo diretório que o atual
nhooyr

Respostas:

18

ATUALIZAÇÃO : Isso não está totalmente correto, pelos motivos mencionados nos comentários. Use a resposta abaixo . Obrigado @ Chrishrage por ir a milha extra :)

A resposta pode ser encontrada pela engenharia reversa em que o bash faz isso /etc/bashrc. Eu tentei muitas abordagens em toda a rede, mas a maneira da Apple parece funcionar melhor (vá entender).

No seu .zshrcadd, adicione o seguinte

# Set Apple Terminal.app resume directory
if [[ $TERM_PROGRAM == "Apple_Terminal" ]] && [[ -z "$INSIDE_EMACS" ]] {
  function chpwd {
    local SEARCH=' '
    local REPLACE='%20'
    local PWD_URL="file://$HOSTNAME${PWD//$SEARCH/$REPLACE}"
    printf '\e]7;%s\a' "$PWD_URL"
  }

  chpwd
}

Feliz retomada.

Para esclarecer, esta resposta refere-se à mensagem misteriosa nas preferências Terminal.app do OS X Lion:

** Os programas notificam o Terminal do diretório de trabalho atual usando seqüências de escape. Pode ser necessário configurar seu shell ou outros programas para ativar esse comportamento. *

Esta resposta funciona quando você está usando o zsh como seu shell. O resumo do terminal para o bash já foi implementado pela Apple.

capitão
fonte
1
Provavelmente não é uma grande coisa na prática, mas eu vejo o estoque / etc / bashrc tem a última linha chpwdcomo printf '\e]7;%s\a' "$PWD_URL"com as aspas duplas. Obrigado pela dica.
Ryan McCuaig 02/08/19
Isso agora está chegando ao oh-my-zsh (consulte github.com/robbyrussell/oh-my-zsh/pull/522 ). Você precisará ter certeza de que ativou o plugin osx no seu zshrc.
Ryan McCuaig
2
Observe também que esse código codifica apenas espaços por cento. Para obter pontos de bônus, faça com que ele codifique em porcentagem todos os caracteres ilegais de URL (e veja se você pode fazê-lo sem chamar nenhum programa). Isso é importante se você deseja que ele funcione com todos os nomes de caminho válidos. Além disso, alguns caracteres nem sequer são considerados parte das seqüências de escape; portanto, é necessária a codificação percentual para levá-los ao terminal. Consegui fazer isso no bash, mas ainda não tentei testá-lo com o zsh.
Chris Page
1
As aspas em torno de "$ PWD_URL" são necessárias para impedir que o nome do caminho seja alterado. EDIT: Isso é necessário no bash, mas opcional no zsh. Prefiro usar as aspas de forma consistente, por isso é portátil.
Chris Page
Obrigado Ryan, Chris. Atualizei o script para usar aspas duplas para obter consistência.
Captainpete
27

Aqui está a minha adaptação do / etc / bashrc para zsh. Incluímos a codificação percentual de todos os caracteres de URL que a exigem, o que é importante se você deseja que isso funcione com todos os nomes de arquivos e diretórios válidos.

Isso registra um precmdgancho, que permite que mais de uma função seja registrada em outros scripts e arquivos de configuração.

ATUALIZADO em março de 2019: defina LC_ALLcomo vazio para que não seja substituído LC_CTYPE. Use precmdpara atualizar o diretório ativo em cada prompt, em vez de usá chpwd-lo para atualizá-lo toda vez que for alterado - os pipelines de comando podem alterá-lo temporariamente e o terminal não deve exibi-los. Além disso, pode ser útil que cada prompt atualize o estado do terminal, caso tenha sido alterado durante o comando anterior. Use printf -vpara escrever explicitamente na variável em vez de usar a sintaxe do subshell.

# Tell the terminal about the working directory whenever it changes.

if [[ "$TERM_PROGRAM" == "Apple_Terminal" ]] && [[ -z "$INSIDE_EMACS" ]]; then

    update_terminal_cwd() {
        # Identify the directory using a "file:" scheme URL, including
        # the host name to disambiguate local vs. remote paths.

        # Percent-encode the pathname.
        local url_path=''
        {
            # Use LC_CTYPE=C to process text byte-by-byte. Ensure that
            # LC_ALL isn't set, so it doesn't interfere.
            local i ch hexch LC_CTYPE=C LC_ALL=
            for ((i = 1; i <= ${#PWD}; ++i)); do
                ch="$PWD[i]"
                if [[ "$ch" =~ [/._~A-Za-z0-9-] ]]; then
                    url_path+="$ch"
                else
                    printf -v hexch "%02X" "'$ch"
                    url_path+="%$hexch"
                fi
            done
        }

        printf '\e]7;%s\a' "file://$HOST$url_path"
    }

    # Register the function so it is called at each prompt.
    autoload add-zsh-hook
    add-zsh-hook precmd update_terminal_cwd
fi
Chris Page
fonte
Obrigado, a solução aceita não funcionou para mim, mas esta funciona.
Eelco
Este também está funcionando para mim.
Sikachu
4
Note-se também que esta solução já está no oh-my-zsh , basta ativar o terminalappplugin.
Simon
1
Só para esclarecer, @Simon significa que agora está no oh-my-zsh, adicionado desde que esta resposta foi escrita.
Chris Página
Isso é correto, ChrisPage, peço desculpas pelo fraseado ambíguo (o inglês não é minha língua materna). O que eu queria dizer era exatamente isso, você não precisa colar isso no seu .zprofileou o que quer, como fiz antes de perceber que ele está realmente disponível no oh-my-zsh. É de fato a mesma solução e você merece todo o crédito.
18713 Simon