Резюме Zsh-Terminal (OS X Lion)

17

OS X Lion имеет функцию «Возобновить», т.е. при повторном открытии приложения оно восстанавливает все окна и их содержимое. Это работает и для Терминала. Но если вы используете Zsh вместо Bash, он не восстанавливает открытый каталог. Как я могу это исправить?

Симон Перепелица
источник
Относится к ответам ниже: информирование Terminal.app о каталоге также полезно для открытия новых терминалов в том же каталоге, что и текущий
nhooyr

Ответы:

18

ОБНОВЛЕНИЕ : Это не совсем правильно, по причинам, указанным в комментариях. Используйте ответ ниже . Спасибо @ChrisPage за прохождение лишней мили :)

Ответ может быть найден путем обратного инжиниринга, как это делает 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
}

Счастливого возобновления.

Для пояснения этот ответ относится к загадочному сообщению в настройках Terminal X. Lion в OS X:

** Программы уведомляют Терминал о текущем рабочем каталоге, используя escape-последовательности. Вам может потребоваться настроить вашу оболочку или другие программы, чтобы включить это поведение. *

Этот ответ работает, когда вы используете zsh в качестве оболочки. Резюме терминала для bash уже реализовано Apple.

captainpete
источник
1
Вероятно, на практике это не так уж и важно, но я вижу, что в / etc / bashrc последняя строка, chpwdкак printf '\e]7;%s\a' "$PWD_URL"и в двойных кавычках. Спасибо за чаевые.
Райан Маккуэйг
Теперь это нашло свое отражение в oh-my-zsh (см. Github.com/robbyrussell/oh-my-zsh/pull/522 ). Вам нужно убедиться, что вы включили плагин osx в zshrc.
Райан МакКуайг
2
Также обратите внимание, что этот код только в процентах кодирует пробелы. Для получения бонусных баллов сделайте процентное кодирование всех недопустимых символов URL (и посмотрите, сможете ли вы это сделать, не вызывая никаких программ). Это важно, если вы хотите, чтобы он работал со всеми допустимыми путями. Кроме того, некоторые символы даже не считаются частью escape-последовательностей, поэтому для их передачи в терминал требуется кодировка процента. Я смог сделать это для bash, но я не пробовал тестировать его с помощью zsh.
Крис Пейдж
1
Кавычки вокруг "$ PWD_URL" необходимы для предотвращения манипулирования путевым именем. РЕДАКТИРОВАТЬ: Это требуется в Bash, но необязательно в Zsh. Я предпочитаю использовать кавычки последовательно, поэтому он переносим.
Крис Пейдж
Спасибо, Райан, Крис. Я обновил скрипт, чтобы использовать двойные кавычки для согласованности.
капитан
27

Вот моя адаптация / etc / bashrc для zsh. Я включил процентное кодирование всех символов URL, которые в нем нуждаются, что важно, если вы хотите, чтобы это работало со всеми допустимыми именами файлов и каталогов.

Это регистрирует precmdловушку, которая позволяет регистрировать более одной функции в других сценариях и файлах конфигурации.

ОБНОВЛЕНО март 2019 года: установлено LC_ALLпустое значение, чтобы оно не перекрывалось LC_CTYPE. Используется precmdдля обновления рабочего каталога в каждом приглашении, а не chpwdдля обновления его каждый раз, когда он изменяется - командные конвейеры могут временно его менять, и терминал не должен отображать их. Кроме того, может быть полезно, чтобы каждая подсказка обновляла состояние терминала, если оно было изменено во время предыдущей команды. Используется printf -vдля явной записи в переменную вместо использования синтаксиса 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
Крис Пейдж
источник
Спасибо, принятое решение не работает для меня, но это работает.
eelco
Этот работает и для меня.
Сикачу
4
Также следует отметить, что это решение уже есть в oh-my-zsh , просто активируйте terminalappплагин.
Саймон
1
Просто чтобы прояснить, @Simon означает, что это сейчас в oh-my-zsh, добавлено с момента написания этого ответа.
Крис Пейдж
Это правильно @ChrisPage, я прошу прощения за неоднозначное выражение (английский не мой родной язык). Что я хотел сказать, так это то, что вам не нужно вставлять это в свой .zprofileили что-то еще, как я делал до того, как понял, что это действительно доступно в oh-my-zsh. Это на самом деле то же самое решение, и вы заслуживаете всяческих похвал.
Саймон