恢复Zsh终端(OS X Lion)


17

OS X Lion具有“恢复”功能,即,当您重新打开应用程序时,它将恢复所有窗口及其内容。这同样适用于Terminal。但是,如果您使用Zsh而不是Bash,它不会还原打开的目录。我怎样才能解决这个问题?


与下面的答案有关:使terminal.app知道目录对于在与当前目录相同的目录中打开新终端也很有用
nhooyr

Answers:


18

更新:由于注释中提到的原因,这并不完全正确。使用下面的答案。感谢@ChrisPage付出了更多努力:)

答案可以通过反向工程找到bash如何在其中进行/etc/bashrc。我从网上尝试了许多方法,但苹果公司的方法似乎效果最好(见图)。

在您.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用作shell时,此答案有效。苹果已经实施了bash的终端恢复。


1
也许在实践中没有大的事情,但我看股票的/ etc / .bashrc中具有的最后一行chpwdprintf '\e]7;%s\a' "$PWD_URL"用双引号。谢谢你的提示。
Ryan McCuaig

现在,它正在进入oh-my-zsh(请参阅github.com/robbyrussell/oh-my-zsh/pull/522)。您需要确保已打开zshrc中的osx插件。
Ryan McCuaig

2
另请注意,此代码仅对空格进行百分比编码。为了获得加分,请对所有非法URL字符进行百分比编码(并查看是否可以在不调用任何程序的情况下进行编码)。如果您希望它与所有有效的路径名一起使用,这一点很重要。另外,某些字符甚至都不被认为是转义序列的一部分,因此需要百分号编码才能将它们带到终端。我能够为bash做到这一点,但是我还没有尝试使用zsh对其进行测试。
克里斯·佩奇

1
需要使用“ $ PWD_URL”周围的引号来防止路径名被修改。编辑:这在bash中是必需的,但在zsh中是可选的。我更喜欢连续使用引号,这样便于携带。
克里斯·佩奇

谢谢瑞安(Chris)。我已经更新了脚本以使用双引号保持一致。
2011年

27

这是我对zsh的/ etc / bashrc的改编。我已包括所有需要它的URL字符的百分比编码,如果您希望它与所有有效的文件名和目录名一起使用,则这很重要。

这将注册一个precmd挂钩,该挂钩允许在其他脚本和配置文件中注册多个功能。

2019年3月更新:设置LC_ALL为空,因此不会覆盖LC_CTYPE。用于precmd在每个提示符下更新工作目录,而不是在每次chpwd更改时都进行更新-命令管道可能会临时更改它,并且终端不应显示这些目录。同样,如果在上一个命令中更改了终端状态,则每个提示都将更新终端状态可能会有帮助。使用printf -v明确写入该变量,而不是使用子shell语法。

# 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

谢谢,无法接受的解决方案对我不起作用,但是这一解决方案对我有用。
eelco 2011年

这个也为我工作。
sikachu

4
还应注意,该解决方案已经在oh-my-zsh中,只需激活terminalapp插件即可。
西蒙(Simon)

1
只是要清楚,@Simon意味着这是现在的哦,我-zsh的,因为加入这个答案写。
克里斯·佩奇

@ChrisPage是正确的,对于模棱两可的措词我深表歉意(英语不是我的母语)。我只是想说的是,您无需.zprofile像在实现之前就可以将其粘贴到您的东西中一样oh-my-zsh。的确是完全相同的解决方案,您应该得到所有荣誉。
西蒙(Simon)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.