Пользовательское приглашение Bash переписывает себя
Я использую пользовательское приглашение bash для отображения ветки git.
Все находится в /etc/bash/bashrc
:
function formattedGitBranch {
_branch="$(git branch 2>/dev/null | sed -e "/^\s/d" -e "s/^\*\s//")"
# tried these:
echo -e "\e[0;91m ($_branch)"
echo -e "\e[0;91m ($_branch) \e[m"
echo -e $'\e[0;91m'"($_branch)"
echo "($_branch)"
echo "$(tput setaf 2) ($_branch) $(tput setaf 9)"
printf "\e[0;91m ($_branch)"
}
# color is set before function call
PS1='\[\033[01;34m\] \[\033[0;91m\]$(formattedGitBranch) \$\[\033[00m\] '
# color is set inside function
PS1='\[\033[01;34m\] $(formattedGitBranch) \$\[\033[00m\] '
Проблема в том, что когда я устанавливаю цвет для $_branch
в функции, моя подсказка будет перезаписана при достижении EOL:
![mmmmmmmmmmmmp/rainyday.js (master) $ mmmmmmmm]()
Пробовал все возможные варианты обозначения tput
, printf
, $''
.
Я решил проблему, установив цвет только в PS1
:
![ad@gentoo /tmp/rainyday.js (master) $ mmmmmmm]()
Но..
- Я хотел бы знать, почему он переписывает мое приглашение
- Как исправить эту проблему при использовании функции
Я использую Gentoo Linux. GNU bash, verze 4.2.37(1)-release (i686-pc-linux-gnu)
Ответы
Ответ 1
1) Я хотел бы знать, почему он переписывает мое приглашение
Поскольку все символы, не подлежащие печати, должны быть экранированы \[
и \]
иначе readline не может отслеживать курсор правильно позиционировать.
Вы должны поместить \[
и \]
вокруг любых escape-последовательностей без печати в вашем приглашении.
Без \[ \]
bash будет считаться, что байты, составляющие escape-последовательности для цветовых кодов, фактически занимают место на экране, поэтому bash не сможет узнать, где находится курсор.
\[
Начните последовательность непечатаемых символов. (например, последовательности выделения цвета). Эта позволяет bash правильно рассчитать перенос слов.
\]
Завершить последовательность непечатаемых символов. - BashFAQ
... обратите внимание на экраны для непечатаемых символов, это гарантирует, что readline может правильно отслеживать позицию курсора. - ss64.com
2) Как исправить эту проблему при использовании функции
Если вам действительно нужно/нужно устанавливать цвета внутри функции, выход которой используется в PS
, у вас есть 2 варианта:
echo -e
не знает bash \[
\]
, поэтому вам нужно заменить их на \001
и \002
Коды управления ASCII для разграничения непечатаемых символов от печати:
function formattedGitBranch { echo -e "\001\e[0;91m\002 ($_branch)"; }
PS1='$(formattedGitBranch) '
Ответ 2
Строкам типа \e[0;91m
требуется дополнительное цитирование, чтобы предотвратить bash от его длины.
Вставьте эти строки из formattedGitBranch
в \[
и \]
as, \[\e[0;91m\]
Вы сделали это правильно в других местах. Просто пропустил его в формате gitBranch.
Ответ 3
Вы должны позаботиться о непечатаемом символе внутри [\ и /], иначе вы могли бы получить курсор в верхней части командной строки, как и в самом вопросе, поэтому я нашел что-то и просто поделился им: -
Чтобы получить курсор после вывода PS1 в той же строке:
![После]()
несколько примеров:
PS1='[\[email protected]\h:\w]\$
PS1='[\[\033[0;32m\]\[email protected]\h:\[\033[36m\]\W\[\033[0m\]]\$ '
Ссылка: синтаксис для bash PS1