Zsh-Terminal fortsetzen (OS X Lion)

17

OS X Lion verfügt über die Funktion "Fortsetzen". Wenn Sie eine App erneut öffnen, werden alle Fenster und deren Inhalte wiederhergestellt. Das funktioniert auch bei Terminal. Wenn Sie jedoch Zsh anstelle von Bash verwenden, wird das geöffnete Verzeichnis nicht wiederhergestellt. Wie kann ich das beheben?

Simon Perepelitsa
quelle
Bezogen auf die folgenden Antworten: Wenn Sie terminal.app auf das Verzeichnis aufmerksam machen, können Sie auch neue Terminals im selben Verzeichnis wie das aktuelle
öffnen

Antworten:

18

UPDATE : Dies ist aus den in den Kommentaren genannten Gründen nicht ganz korrekt. Verwenden Sie die Antwort unten . Vielen Dank an @ChrisPage für die Extrameile :)

Die Antwort kann durch Reverse Engineering gefunden werden /etc/bashrc. Ich habe viele Ansätze aus dem Internet ausprobiert, aber Apples Weg scheint am besten zu funktionieren (siehe Abbildung).

Fügen .zshrcSie Folgendes hinzu

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

Viel Spaß bei der Wiederaufnahme.

Zur Verdeutlichung bezieht sich diese Antwort auf die mysteriöse Meldung in den Terminal.app-Einstellungen von OS X Lion:

** Programme benachrichtigen das Terminal über Escape-Sequenzen über das aktuelle Arbeitsverzeichnis. Möglicherweise müssen Sie Ihre Shell oder andere Programme konfigurieren, um dieses Verhalten zu aktivieren. *

Diese Antwort funktioniert, wenn Sie zsh als Shell verwenden. Terminal Resume für Bash wurde bereits von Apple implementiert.

Captainpete
quelle
1
Wahrscheinlich keine große Sache in der Praxis, aber ich sehe die Aktie / etc / bashrc hat die letzte Zeile chpwdwie printf '\e]7;%s\a' "$PWD_URL"mit den Anführungszeichen. Danke für den Tipp.
Ryan McCuaig
Dies macht jetzt seinen Weg in oh-my-zsh (siehe github.com/robbyrussell/oh-my-zsh/pull/522 ). Sie müssen sicherstellen, dass Sie das osx-Plugin in Ihrem zshrc aktiviert haben.
Ryan McCuaig
2
Beachten Sie auch, dass dieser Code nur Leerzeichen in Prozent codiert. Wenn Sie Bonuspunkte erhalten möchten, müssen Sie alle unzulässigen URL-Zeichen in Prozent kodieren (und prüfen, ob Sie dies tun können, ohne Programme aufzurufen). Dies ist wichtig, wenn alle gültigen Pfadnamen verwendet werden sollen. Außerdem werden einige Zeichen nicht einmal als Teil von Escape-Sequenzen betrachtet, sodass eine Prozentcodierung erforderlich ist, um sie zum Terminal zu bringen. Ich konnte dies für bash tun, habe es aber nicht mit zsh getestet.
Chris Seite
1
Die Anführungszeichen um "$ PWD_URL" sind erforderlich, um zu verhindern, dass der Pfadname verschoben wird. BEARBEITEN: Dies ist in bash erforderlich, aber optional in zsh. Ich bevorzuge es, die Anführungszeichen konsequent zu verwenden, damit es portabel ist.
Chris Seite
Danke Ryan, Chris. Ich habe das Skript aktualisiert, um die doppelten Anführungszeichen für die Konsistenz zu verwenden.
Captainpete
27

Hier ist meine Anpassung von / etc / bashrc für zsh. Ich habe die Prozentcodierung aller URL-Zeichen eingefügt, die dies erfordern. Dies ist wichtig, wenn Sie möchten, dass dies mit allen gültigen Datei- und Verzeichnisnamen funktioniert.

Dadurch wird ein precmdHook registriert , mit dem mehr als eine Funktion in anderen Skripten und Konfigurationsdateien registriert werden kann.

AKTUALISIERT März 2019: Auf LC_ALLleer setzen, damit es nicht außer Kraft gesetzt wird LC_CTYPE. Verwenden Sie precmddiese Option, um das Arbeitsverzeichnis bei jeder Eingabeaufforderung chpwdzu aktualisieren, anstatt es bei jeder Änderung zu aktualisieren. Befehls-Pipelines können es vorübergehend ändern, und das Terminal sollte diese nicht anzeigen. Es kann auch hilfreich sein, bei jeder Eingabeaufforderung den Terminalstatus zu aktualisieren, falls er während des vorherigen Befehls geändert wurde. Verwenden Sie printf -vdiese Option, um explizit in die Variable zu schreiben, anstatt die Subshell-Syntax zu verwenden.

# 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
quelle
Danke, die akzeptierte Lösung hat bei mir nicht funktioniert, aber diese tut es.
Eelco
Dieser arbeitet auch für mich.
Sikachu
4
Es sollte auch beachtet werden, dass diese Lösung bereits in oh-my-zsh ist , aktivieren Sie einfach das terminalappPlugin.
Simon
1
Nur um klar zu sein, @Simon bedeutet, dass dies jetzt in oh-my-zsh ist, da diese Antwort geschrieben wurde.
Chris Seite
Das ist richtig @ChrisPage, ich entschuldige mich für die mehrdeutige Formulierung (Englisch ist nicht meine Muttersprache). Was ich damit sagen wollte, war, dass Sie dies nicht in Ihr .zprofileoder was auch immer einfügen müssen , wie ich es getan habe, bevor Sie realisiert haben, dass es tatsächlich in verfügbar ist oh-my-zsh. Es ist in der Tat genau die gleiche Lösung und Sie verdienen alle Ehre.
Simon