Riprendi Terminale Zsh (OS X Lion)


17

OS X Lion ha la funzione "Riprendi", ovvero quando riapri un'app ripristina tutte le finestre e i loro contenuti. Funziona anche con Terminal. Ma se usi Zsh invece di Bash non ripristina la directory aperta. Come posso risolvere questo problema?


In relazione alle seguenti risposte: rendere terminal.app consapevole della directory è utile anche per aprire nuovi terminali nella stessa directory di quella corrente
nhooyr

Risposte:


18

AGGIORNAMENTO : Questo non è del tutto corretto, per i motivi menzionati nei commenti. Usa la risposta qui sotto . Grazie @ChrisPage per aver fatto il possibile :)

La risposta può essere trovata dal reverse engineering su come fa bash /etc/bashrc. Ho provato molti approcci da rete ma il modo in cui Apple sembra funzionare meglio (vai alla figura).

Nel tuo .zshrcaggiungi quanto segue

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

Felice ripresa.

Per chiarire, questa risposta riguarda il misterioso messaggio nelle preferenze di OS X Lion's Terminal.app:

** I programmi comunicano al Terminale la directory di lavoro corrente usando sequenze di escape. Potrebbe essere necessario configurare la shell o altri programmi per abilitare questo comportamento. *

Questa risposta funziona quando usi zsh come shell. Terminal Resume per bash è già stato implementato da Apple.


1
Probabilmente non è una grande cosa in pratica, ma vedo che lo stock / etc / bashrc ha l'ultima riga di chpwdcome printf '\e]7;%s\a' "$PWD_URL"con le doppie virgolette. Grazie per il consiglio.
Ryan McCuaig,

Questo si sta facendo strada in oh-my-zsh (vedi github.com/robbyrussell/oh-my-zsh/pull/522 ). Dovrai assicurarti di aver attivato il plugin osx in zshrc.
Ryan McCuaig,

2
Si noti inoltre che questo codice codifica solo gli spazi. Per i punti bonus, codifica in percentuale tutti i caratteri URL illegali (e vedi se riesci a farlo senza invocare alcun programma). Questo è importante se vuoi che funzioni con tutti i nomi di percorso validi. Inoltre, alcuni personaggi non sono nemmeno considerati parte delle sequenze di escape, quindi è necessaria la codifica in percentuale per portarli al terminale. Sono stato in grado di farlo per bash, ma non ho provato a provarlo con zsh.
Chris Page

1
Le virgolette intorno a "$ PWD_URL" sono necessarie per impedire il munging del percorso. EDIT: questo è richiesto in bash, ma facoltativo in zsh. Preferisco usare le virgolette in modo coerente, quindi è portatile.
Chris Page

Grazie Ryan, Chris. Ho aggiornato lo script per usare le doppie virgolette per coerenza.
capitano

27

Ecco il mio adattamento di / etc / bashrc per zsh. Ho incluso la codifica percentuale di tutti i caratteri URL che lo richiedono, il che è importante se si desidera che funzioni con tutti i nomi di file e directory validi.

Ciò registra un precmdhook, che consente di registrare più di una funzione in altri script e file di configurazione.

AGGIORNATO Marzo 2019: impostato LC_ALLsu vuoto in modo che non abbia la precedenza LC_CTYPE. Utilizzare precmdper aggiornare la directory di lavoro a ciascun prompt anziché utilizzare chpwdper aggiornarla ogni volta che viene modificata: le pipeline di comandi potrebbero modificarla temporaneamente e il terminale non dovrebbe visualizzarle. Inoltre, può essere utile che ogni prompt aggiorni lo stato del terminale nel caso in cui sia stato modificato durante il comando precedente. Utilizzare printf -vper scrivere in modo esplicito nella variabile anziché utilizzare la sintassi della 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

Grazie, la soluzione accettata non ha funzionato per me, ma questa funziona.
eelco,

Questo funziona anche per me.
Sikachu,

4
Va anche notato che questa soluzione è già in oh-my-zsh , basta attivare il terminalappplugin.
Simon,

1
Per essere chiari, @Simon significa che questo è ora in oh-my-zsh, aggiunto da quando è stata scritta questa risposta.
Chris Page

Questo è corretto @ChrisPage, mi scuso per il fraseggio ambiguo (l'inglese non è la mia lingua madre). Quello che volevo dire era che non hai bisogno di incollarlo nel tuo .zprofileo in qualsiasi altra cosa, come ho fatto prima di rendermi conto che in realtà è disponibile in oh-my-zsh. È in realtà la stessa identica soluzione e ti meriti tutto il merito.
Simon,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.