Reanudar Zsh-Terminal (OS X Lion)

17

OS X Lion tiene la función "Reanudar", es decir, cuando vuelve a abrir una aplicación, restaura todas las ventanas y sus contenidos. Eso también funciona para la Terminal. Pero si usa Zsh en lugar de Bash, no restaura el directorio abierto. ¿Cómo puedo arreglar esto?

Simon Perepelitsa
fuente
Relacionado con las respuestas a continuación: hacer que terminal.app conozca el directorio también es útil para abrir nuevas terminales en el mismo directorio que el actual
nhooyr

Respuestas:

18

ACTUALIZACIÓN : Esto no es del todo correcto, por las razones mencionadas en los comentarios. Usa la respuesta a continuación . Gracias @ChrisPage por hacer un esfuerzo adicional :)

La respuesta se puede encontrar mediante ingeniería inversa cómo bash lo hace /etc/bashrc. Intenté muchos enfoques desde la red, pero el camino de Apple parece funcionar mejor (vaya a la figura).

En su .zshrccomplemento lo siguiente

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

Feliz reanudación.

Para aclarar, esta respuesta se refiere al misterioso mensaje en las preferencias de OS X Lion's Terminal.app:

** Los programas notifican a Terminal el directorio de trabajo actual utilizando secuencias de escape. Es posible que deba configurar su shell u otros programas para habilitar este comportamiento. *

Esta respuesta funciona cuando usas zsh como shell. La reanudación de terminal para bash ya ha sido implementada por Apple.

capitanpete
fuente
1
Probablemente no es un gran paso en la práctica, pero no veo la acción / etc / bashrc tiene la última línea de chpwdcomo printf '\e]7;%s\a' "$PWD_URL"con las comillas dobles. Gracias por el consejo.
Ryan McCuaig
Esto ahora está llegando a oh-my-zsh (ver github.com/robbyrussell/oh-my-zsh/pull/522 ). Deberá asegurarse de haber activado el complemento osx en su zshrc.
Ryan McCuaig
2
También tenga en cuenta que este código solo codifica por ciento los espacios. Para obtener puntos de bonificación, haga que codifique en porcentaje todos los caracteres de URL ilegales (y vea si puede hacerlo sin invocar ningún programa). Esto es importante si desea que funcione con todos los nombres de ruta válidos. Además, algunos caracteres ni siquiera se consideran parte de las secuencias de escape, por lo que se requiere una codificación porcentual para llevarlos al terminal. Pude hacer esto para bash, pero no he intentado probarlo con zsh.
Chris Page
1
Las comillas alrededor de "$ PWD_URL" son necesarias para evitar que el nombre de ruta se modifique. EDITAR: Esto es obligatorio en bash, pero opcional en zsh. Prefiero usar las comillas de manera consistente para que sea portátil.
Chris Page
Gracias Ryan, Chris. He actualizado el script para utilizar las comillas dobles para mayor coherencia.
captainpete
27

Aquí está mi adaptación de / etc / bashrc para zsh. Incluí la codificación porcentual de todos los caracteres de URL que lo requieren, lo cual es importante si desea que esto funcione con todos los nombres válidos de archivos y directorios.

Esto registra un precmdenlace, que permite registrar más de una función en otros scripts y archivos de configuración.

ACTUALIZADO en marzo de 2019: se establece LC_ALLen vacío para que no se anule LC_CTYPE. Utilícelo precmdpara actualizar el directorio de trabajo en cada solicitud en lugar de utilizarlo chpwdpara actualizarlo cada vez que se modifique; los canales de comandos pueden modificarlo temporalmente y el terminal no debería mostrarlos. Además, puede ser útil que cada solicitud actualice el estado del terminal en caso de que se haya cambiado durante el comando anterior. Use printf -vpara escribir explícitamente en la variable en lugar de usar la sintaxis de 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
fuente
Gracias, la solución aceptada no funcionó para mí, pero esta sí.
eelco
Este también está funcionando para mí.
sikachu
44
También debe tenerse en cuenta que esta solución ya está en oh-my-zsh , solo active el terminalappcomplemento.
Simon
1
Para ser claros, @Simon significa que ahora está en oh-my-zsh, agregado desde que se escribió esta respuesta.
Chris Page
Eso es correcto @ChrisPage, pido disculpas por la redacción ambigua (el inglés no es mi lengua materna). Lo que quise decir fue que no necesitas pegar esto en tu .zprofileo lo que sea, como hice antes de darme cuenta de que en realidad está disponible oh-my-zsh. De hecho, es exactamente la misma solución y usted merece todo el crédito.
Simon