Zsh-Terminalの再開(OS X Lion)


17

OS X Lionには「再開」機能があります。つまり、アプリを再度開くと、すべてのウィンドウとそのコンテンツが復元されます。ターミナルでも同様に機能します。ただし、Bashの代わりにZshを使用すると、開いているディレクトリは復元されません。どうすれば修正できますか?


以下の回答に関連する:ディレクトリのterminal.appを認識させることも現在のものと同じディレクトリに新しい端末を開くために有用である
nhooyr

回答:


18

更新:これは、コメントに記載されている理由により、完全に正しいわけではありません。以下の回答を使用してください。@ChrisPageに1マイル進んでくれてありがとう:)

答えは、bashがどのようにそれを行うかをリバースエンジニアリングすることで見つけることができます/etc/bashrc。私はネット上から多くのアプローチを試みましたが、Appleの方法が最もうまくいくようです(図を参照)。

.zshrc以下を追加してください

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

ハッピー再開。

明確にするために、この回答はOS X LionのTerminal.appの設定にある不思議なメッセージに関するものです。

**プログラムは、エスケープシーケンスを使用して現在の作業ディレクトリをターミナルに通知します。この動作を有効にするには、シェルまたは他のプログラムを構成する必要がある場合があります。*

この答えは、zshをシェルとして使用しているときに機能します。bashのTerminal Resumeは、すでにAppleによって実装されています。


1
おそらく実際には大きなことではありませんが、株式/ etc / bashrcには二重引用符とchpwd同様に最後の行がありprintf '\e]7;%s\a' "$PWD_URL"ます。ヒントをありがとう。
ライアンマッキューグ

これは現在、oh-my-zshに移行しています(github.com/robbyrussell/oh-my-zsh/pull/522を参照)。zshrcでosxプラグインを有効にしていることを確認する必要があります。
ライアンマッキューグ

2
また、このコードはスペースのみをパーセントでエンコードすることに注意してください。ボーナスポイントについては、すべての違法なURL文字をパーセントエンコードします(プログラムを起動せずにそれができるかどうかを確認します)。これは、すべての有効なパス名で機能させる場合に重要です。また、一部の文字はエスケープシーケンスの一部とさえ見なされないため、端末に到達するにはパーセントエンコーディングが必要です。bashでこれを行うことはできましたが、zshでテストしてみませんでした。
クリスページ

1
パス名が変更されないようにするには、「$ PWD_URL」を囲む引用符が必要です。編集:これはbashでは必須ですが、zshではオプションです。移植性を保つために、引用符を一貫して使用することを好みます。
クリスページ

ライアン、クリスに感謝します。一貫性を保つために二重引用符を使用するようにスクリプトを更新しました。
キャプテンピーター

27

zshに対する/ etc / bashrcの私の適応は次のとおりです。これを必要とするすべてのURL文字のパーセントエンコーディングを含めました。これは、これをすべての有効なファイル名およびディレクトリ名で機能させる場合に重要です。

これprecmdによりフックが登録され、複数の関数を他のスクリプトおよび構成ファイルに登録できます。

2019年3月更新:をLC_ALL上書きしないように空に設定しますLC_CTYPE。変更するたびに更新するprecmd代わりに、各プロンプトで作業ディレクトリを更新するために使用します。chpwdコマンドパイプラインによって一時的に変更される場合があり、端末はそれらを表示しません。また、前のコマンドで端末の状態が変更された場合に備えて、各プロンプトで端末の状態を更新すると役立つ場合があります。printf -vサブシェル構文を使用する代わりに、変数に明示的に書き込むために使用します。

# 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

おかげで、受け入れられた解決策は私にとってはうまくいきませんでしたが、これはうまくいきます。
アールコ

これも私のために働いています。
シカチュ

4
また、このソリューションは既にoh-my-zshにあり、terminalappプラグインをアクティブ化するだけであることに注意してください。
サイモン

1
明確にするために、@ Simonは、これがoh-my-zshになったことを意味します。これは、この回答が書かれてから追加されました。
クリスページ

それは正しい@ChrisPageです。曖昧な言い回しをおaびします(英語は私の母国語ではありません)。私が言いたいのは、これ.zprofileを実際に利用できることに気付く前にやったように、あなたはこれを自分のものに貼り付ける必要はありませんでしたoh-my-zsh。それは実際にはまったく同じ解決策であり、あなたはすべての功績に値します。
サイモン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.