Lanjutkan Zsh-Terminal (OS X Lion)

17

OS X Lion memiliki fitur "Lanjutkan", yaitu ketika Anda membuka kembali aplikasi, ia mengembalikan semua jendela dan kontennya. Itu juga berfungsi untuk Terminal. Tetapi jika Anda menggunakan Zsh bukan Bash itu tidak mengembalikan direktori yang dibuka. Bagaimana saya bisa memperbaikinya?

Simon Perepelitsa
sumber
Terkait dengan jawaban di bawah ini: membuat terminal.app menyadari direktori ini juga berguna untuk membuka terminal baru di direktori yang sama dengan yang sekarang
nhooyr

Jawaban:

18

UPDATE : Ini tidak sepenuhnya benar, untuk alasan yang disebutkan dalam komentar. Gunakan jawaban di bawah ini . Terima kasih @ChrisPage untuk bekerja lebih keras :)

Jawabannya dapat ditemukan dengan rekayasa balik bagaimana bash melakukannya /etc/bashrc. Saya mencoba banyak pendekatan dari seluruh internet tetapi cara Apple tampaknya bekerja paling baik (angka).

Di .zshrctambahkan Anda yang berikut ini

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

Selamat melanjutkan.

Untuk memperjelas, jawaban ini berkaitan dengan pesan misterius di preferensi Terminal X. OS X Lion:

** Program memberi tahu Terminal tentang direktori kerja saat ini menggunakan urutan pelarian. Anda mungkin perlu mengonfigurasi shell atau program lain untuk mengaktifkan perilaku ini. *

Jawaban ini berfungsi saat Anda menggunakan zsh sebagai shell. Terminal Resume untuk bash telah diterapkan oleh Apple.

kapten
sumber
1
Mungkin bukan hal besar dalam praktek, tapi saya melihat stock / etc / bashrc memiliki baris terakhir chpwdseperti printf '\e]7;%s\a' "$PWD_URL"dengan tanda kutip ganda. Terima kasih atas tipnya.
Ryan McCuaig
Ini sekarang sedang menuju oh-my-zsh (lihat github.com/robbyrussell/oh-my-zsh/pull/522 ). Anda harus memastikan bahwa Anda telah mengaktifkan plugin osx di zshrc Anda.
Ryan McCuaig
2
Perhatikan juga bahwa kode ini hanya menyandikan persen ruang. Untuk poin bonus, buat itu enkode semua karakter URL ilegal (dan lihat apakah Anda bisa melakukannya tanpa menjalankan program apa pun). Ini penting jika Anda ingin itu berfungsi dengan semua nama path yang valid. Selain itu, beberapa karakter bahkan tidak dianggap sebagai bagian dari urutan pelarian, sehingga diperlukan enkode persen untuk membawanya ke terminal. Saya dapat melakukan ini untuk bash, tetapi saya belum mencoba mengujinya dengan zsh.
Chris Page
1
Kutipan di sekitar "$ PWD_URL" diperlukan untuk mencegah agar nama path tidak di-greened. EDIT: Ini diperlukan dalam bash, tetapi opsional dalam zsh. Saya lebih suka menggunakan tanda kutip secara konsisten sehingga mudah dibawa-bawa.
Chris Page
Terima kasih Ryan, Chris. Saya telah memperbarui skrip untuk menggunakan tanda kutip ganda untuk konsistensi.
Kapten
27

Inilah adaptasi saya dari / etc / bashrc untuk zsh. Saya telah menyertakan penyandian-persen semua karakter URL yang memerlukannya, yang penting jika Anda ingin ini berfungsi dengan semua nama file dan direktori yang valid.

Ini mendaftarkan sebuah precmdkait, yang memungkinkan lebih dari satu fungsi untuk didaftarkan di skrip lain dan file konfigurasi.

DIPERBARUI Maret 2019: Setel LC_ALLke kosong agar tidak diganti LC_CTYPE. Gunakan precmduntuk memperbarui direktori yang berfungsi pada setiap prompt alih-alih menggunakan chpwduntuk memperbaruinya setiap kali diubah — saluran pipa perintah dapat mengubahnya sementara dan terminal tidak akan menampilkannya. Juga, akan sangat membantu jika setiap prompt memperbarui status terminal seandainya itu diubah selama perintah sebelumnya. Gunakan printf -vuntuk menulis secara eksplisit ke variabel alih-alih menggunakan sintaks 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
sumber
Terima kasih, solusi yang diterima tidak bekerja untuk saya, tetapi yang ini berhasil.
eelco
Yang ini juga bekerja untuk saya.
sikachu
4
Perlu juga dicatat bahwa solusi ini sudah ada di oh-my-zsh , cukup aktifkan terminalappplugin.
Simon
1
Supaya jelas, @Simon berarti ini sekarang dalam oh-my-zsh, ditambahkan sejak jawaban ini ditulis.
Chris Page
Itu benar @ChrisPage, saya minta maaf untuk frasa ambigu (bahasa Inggris bukan bahasa ibu saya). Apa yang ingin saya katakan adalah hanya itu, Anda tidak perlu menempel ini di Anda .zprofileatau apa pun, seperti yang saya lakukan sebelum menyadari itu sebenarnya tersedia di oh-my-zsh. Memang dalam akta solusi yang sama persis dan Anda layak semua kredit.
Simon