Хобрук: Ваш путь к мастерству в программировании

Тема ZSH не обновляется из функции

Я пытаюсь написать тему ZSH, которая отображает определенные символы в зависимости от статуса Git (если в репозитории git). Ранее я реализовал эту тему в Bash, но у меня возникли проблемы с переходом на ZSH. Это, вероятно, моя собственная вина, но если кто-то может помочь, это будет очень признательно.

Соответствующая часть моей темы:

local jobs="%{$terminfo[bold]$fg[cyan]%}[%{$fg[magenta]%}%j%{$terminfo[bold]$fg[cyan]%}]%{$reset_color%}"
local git_branch='$(git_prompt_info)%{$reset_color%}'
local current_dir="%{$terminfo[bold]$fg[orange]%}%~%{$reset_color%}"

if [[ $UID -eq 0 ]]; then
    local user_host="%{$terminfo[bold]$fg[red]%}%n@%m%{$reset_color%}"
    local user_symbol="#"
else
    local user_host="%{$terminfo[bold]$fg[green]%}%n@%{$fg[red]%}%m%{$reset_color%}"
    local user_symbol="$"
fi

function git_has_unstaged() {
  if ! $(git diff-files --quiet --ignore-submodules --); then
      echo -n "%*! ";
  fi;
}

function git_has_uncommitted() {
  if [ ! $(git diff --quiet --ignore-submodules --cached; echo "${?}") = "0" ]; then
      echo -n "%*+ ";
  fi;
}

function git_has_untracked() {
  if [ -n "$(git ls-files --others --exclude-standard)" ]; then
      echo -n "%*? ";
  fi;
}

function git_has_stashed() {
  if $(git rev-parse --verify refs/stash &>/dev/null); then
      echo -n "%*$ ";
  fi;
}

function git_status_symbols() {
  echo -n "%{$terminfo[bold]$fg[blue]%}[";
  if [ $(git rev-parse --is-inside-work-tree &>/dev/null; echo "${?}") = "0" ]; then
    #Now is it Git repo
    if [ "$(git rev-parse --is-inside-git-dir 2> /dev/null)" = "false" ]; then
      # check if the current directory is in .git before running git checks
      # Ensure the index is up to date.
      git update-index --really-refresh -q &>/dev/null;
      git_has_uncommitted;
      git_has_unstaged;
      git_has_untracked;
      git_has_stashed;
    fi;
  fi;
  echo -n "]%{$reset_color%}";
}

PROMPT="╭─${user_host} ${current_dir} ${jobs} ${git_branch} $(git_status_symbols)
╰─%B${user_symbol}%b "
ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[yellow]%}‹"
ZSH_THEME_GIT_PROMPT_SUFFIX="›%{$reset_color%}"

Моя проблема в том, что значение git_status_symbols в подсказке не обновляется в соответствии с обновлениями в файле fs/git. Пример:

╭─theonlyjohnny@phoenix ~/configs [0] ‹bored› []
╰─$ git status
On branch bored
Your branch is up to date with 'origin/bored'.

nothing to commit, working tree clean
╭─theonlyjohnny@phoenix ~/configs [0] ‹bored› []
╰─$ touch ./t
╭─theonlyjohnny@phoenix ~/configs [0] ‹bored› []
╰─$ git_has_untracked
%*? %                                                                                                                                                                                                                                                                                                               ╭─theonlyjohnny@phoenix ~/configs [0] ‹bored› []
╰─$ zsh
╭─theonlyjohnny@phoenix ~/configs [0] ‹bored› [1:50:37? ]
╰─$
╭─theonlyjohnny@phoenix ~/configs [0] ‹bored› [1:52:14? ]
╰─$ rm t
╭─theonlyjohnny@phoenix ~/configs [0] ‹bored› [1:52:16? ]
╰─$ git_has_untracked
╭─theonlyjohnny@phoenix ~/configs [0] ‹bored› [1:52:22? ]
╰─$ zsh
╭─theonlyjohnny@phoenix ~/configs [0] ‹bored› []
╰─$

Как видите, в то время как моя функция git_has_untracked правильно повторяет ?, подсказка не отражает это, пока я не запущу новую оболочку. После удаления неотслеживаемого файла функция git_has_untracked больше ничего не отображает. Что интересно, так это то, что время все еще обновляется. При создании новой оболочки подсказка снова верна.

Любая помощь приветствуется! Спасибо

08.03.2019

Ответы:


1

Это происходит потому, что ваша переменная PROMPT содержит подстановку команды $(git_status_symbols). Эта оценка происходит один раз во время назначения, а не при каждом расширении PROMPT.

Самый простой способ исправить это — использовать precmd, который заполняет массив psvar, а затем вставлять это значение в приглашение в форме %v. Например:

precmd () { psvar[1]=$(git_status_symbols); }
PROMPT="╭─${user_host} ${current_dir} ${jobs} ${git_branch} %1v
╰─%B${user_symbol}%b "

Кроме того, имейте в виду, что zsh имеет собственную поддержку vcs (для Git и других), которую вы можете использовать или не использовать вместо написания собственного кода.

08.03.2019
Новые материалы

Создание кнопочного меню с использованием HTML, CSS и JavaScript
Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

Внедрите OAuth в свои веб-приложения для повышения безопасности
OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

Классы в JavaScript
class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

Как свинг-трейдеры могут использовать ИИ для больших выигрышей
По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..

Как построить любой стол
Я разработчик программного обеспечения. Я люблю делать вещи и всегда любил. Для меня программирование всегда было способом создавать вещи, используя только компьютер и мое воображение...

Обзор: Машинное обучение: классификация
Только что закончил третий курс курса 4 часть специализации по машинному обучению . Как и второй курс, он был посвящен низкоуровневой работе алгоритмов машинного обучения. Что касается..

Разработка расширений Qlik Sense с qExt
Использование современных инструментов веб-разработки для разработки крутых расширений Вы когда-нибудь хотели кнопку для установки переменной в приложении Qlik Sense? Когда-нибудь просили..