Reprendre Zsh-Terminal (OS X Lion)

17

OS X Lion dispose de la fonction "Reprendre", c'est-à-dire que lorsque vous rouvrez une application, elle restaure toutes les fenêtres et leur contenu. Cela fonctionne également pour Terminal. Mais si vous utilisez Zsh au lieu de Bash, il ne restaure pas le répertoire ouvert. Comment puis-je réparer cela?

Simon Perepelitsa
la source
En relation avec les réponses ci-dessous: rendre terminal.app conscient du répertoire est également utile pour ouvrir de nouveaux terminaux dans le même répertoire que celui actuel
nhooyr

Réponses:

18

MISE À JOUR : Ce n'est pas tout à fait correct, pour les raisons mentionnées dans les commentaires. Utilisez la réponse ci-dessous . Merci @ChrisPage d'avoir fait un effort supplémentaire :)

La réponse peut être trouvée en inversant la façon dont bash le fait /etc/bashrc. J'ai essayé de nombreuses approches de partout sur le net, mais la manière d'Apple semble fonctionner le mieux (allez comprendre).

Dans votre .zshrcajouter ce qui suit

# 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
}

Bonne reprise.

Pour clarifier, cette réponse se rapporte au mystérieux message dans les préférences Terminal.app d'OS X Lion:

** Les programmes informent Terminal du répertoire de travail actuel à l'aide de séquences d'échappement. Vous devrez peut-être configurer votre shell ou d'autres programmes pour activer ce comportement. *

Cette réponse fonctionne lorsque vous utilisez zsh comme shell. Terminal Resume pour bash a déjà été implémenté par Apple.

capitainepete
la source
1
Probablement pas une grande chose dans la pratique, mais je vois que le stock / etc / bashrc a la dernière ligne chpwdcomme printf '\e]7;%s\a' "$PWD_URL"avec les guillemets doubles. Merci pour le conseil.
Ryan McCuaig
Cela fait maintenant son chemin dans oh-my-zsh (voir github.com/robbyrussell/oh-my-zsh/pull/522 ). Vous devrez vous assurer que vous avez activé le plugin osx dans votre zshrc.
Ryan McCuaig
2
Notez également que ce code n'encode que des espaces en pourcentage. Pour les points bonus, faites-le encoder en pourcentage tous les caractères URL illégaux (et voyez si vous pouvez le faire sans appeler de programme). Ceci est important si vous souhaitez qu'il fonctionne avec tous les chemins d'accès valides. De plus, certains caractères ne sont même pas considérés comme faisant partie des séquences d'échappement, donc un encodage en pourcentage est nécessaire pour les amener au terminal. J'ai pu le faire pour bash, mais je n'ai pas essayé de le tester avec zsh.
Chris Page
1
Les guillemets autour de "$ PWD_URL" sont nécessaires pour empêcher le nom de chemin d'être munged. EDIT: Ceci est requis dans bash, mais facultatif dans zsh. Je préfère utiliser les guillemets de manière cohérente pour que ce soit portable.
Chris Page
Merci Ryan, Chris. J'ai mis à jour le script pour utiliser les guillemets doubles pour la cohérence.
captainpete
27

Voici mon adaptation de / etc / bashrc pour zsh. J'ai inclus le codage en pourcentage de tous les caractères d'URL qui en ont besoin, ce qui est important si vous souhaitez que cela fonctionne avec tous les noms de fichiers et de répertoires valides.

Cela enregistre un precmdhook, qui permet d' enregistrer plus d'une fonction dans d'autres scripts et fichiers de configuration.

MISE À JOUR mars 2019: défini LC_ALLsur vide pour qu'il ne remplace pas LC_CTYPE. Utilisez precmdpour mettre à jour le répertoire de travail à chaque invite au lieu d'utiliser chpwdpour le mettre à jour chaque fois qu'il est modifié - les pipelines de commandes peuvent le changer temporairement et le terminal ne doit pas les afficher. En outre, il peut être utile que chaque invite mette à jour l'état du terminal au cas où il aurait été modifié lors de la commande précédente. Utilisez printf -vpour écrire explicitement dans la variable au lieu d'utiliser la syntaxe de sous-shell.

# 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
la source
Merci, la solution acceptée n'a pas fonctionné pour moi, mais celle-ci fonctionne.
eelco
Celui-ci fonctionne aussi pour moi.
sikachu
4
Il convient également de noter que cette solution est déjà en oh-my-zsh , il suffit d'activer le terminalappplugin.
Simon
1
Juste pour être clair, @Simon signifie que c'est maintenant dans oh-my-zsh, ajouté depuis que cette réponse a été écrite.
Chris Page
C'est correct @ChrisPage, je m'excuse pour la formulation ambiguë (l'anglais n'est pas ma langue maternelle). Ce que je voulais dire était juste que, vous n'avez pas besoin de coller ceci dans votre .zprofileou quoi que ce soit, comme je l'ai fait avant de réaliser qu'il est en fait disponible en oh-my-zsh. C'est en effet exactement la même solution et vous méritez tout le crédit.
Simon