我的配置的想法PS1
是显示一些扩展信息,例如 Mercurial 或 Git 存储库状态、命令执行时间等。提示符被分成两行,因为它产生太多字符而无法放入一行。这是我的PS1
(.bashrc
不确定这里是否需要整个源代码):
function prompt_status {
local color_app="\e[1;38;5;214m"
local color_branch="\e[1;38;5;32m"
local color_revision="\e[0;38;5;64m"
if git rev-parse --is-inside-work-tree &> /dev/null; then
local branch="$(git rev-parse --abbrev-ref HEAD | tr -d '\n')"
local revision="$(git rev-parse HEAD | tr -d '\n')"
echo -ne $color_app"git "$color_branch"$branch "$color_revision"($revision)"
elif hg status &> /dev/null; then
local branch="$(hg branch | tr -d '\n')"
local revision_number="$(hg identify -n | tr -d '\n')"
local revision="$(hg parent --template '{node}' | tr -d '\n')"
echo -ne $color_app"hg "$color_branch"$branch "$color_revision"($revision_number:$revision)"
else
return
fi
echo -e " \e[0m"
}
function prompt_return_value {
RET=$?
if [[ $RET -eq 0 ]]; then
echo -ne "" #echo -ne "\e[32m$RET\e[0m"
else
echo -ne "\e[1;37;41m$RET\e[0m "
fi
}
function timer_start {
timer=${timer:-$SECONDS}
}
function timer_stop {
seconds_elapsed=$(($SECONDS - $timer))
unset timer
}
function prompt_seconds_elapsed {
local c;
local t=${seconds_elapsed}s
if [ $seconds_elapsed -ge 60 ]; then
c=196
t=$(format_seconds $seconds_elapsed)
elif [ $seconds_elapsed -ge 20 ]; then
c=214
elif [ $seconds_elapsed -ge 10 ]; then
c=100
elif [ $seconds_elapsed -ge 5 ]; then
c=34
elif [ $seconds_elapsed -ge 1 ]; then
c=22
else
return
fi
echo -ne "\e[0;38;5;${c}m${t} \e[0m"
}
function format_seconds {
((h=${1}/3600))
((m=(${1}%3600)/60))
((s=${1}%60))
printf "%02d:%02d:%02d\n" $h $m $s
}
trap 'timer_start' DEBUG
PROMPT_COMMAND=timer_stop
export PS1="\n\e[1;38;5;106m\u@\h \e[0;38;5;136m\w\[\e[0m\]\n\$(prompt_return_value)\$(prompt_seconds_elapsed)\$(prompt_status)\$ "
问题在于,当终端窗口宽度较小时,提示看起来会损坏。这是我从 80 列中得到的结果:
username@some-very-long-hostname ~/tmp/d
06a14b06cac) $ 9866c9d0d26d2b27063a89ee1c330
就像包裹在第二行导致完全混乱(参见中间的 $ 符号)。对于较大的终端列数(例如 120),它几乎完美地工作:
username@some-very-long-hostname ~/tmp/d
hg default (0:69866c9d0d26d2b27063a89ee1c3306a14b06cac) $
我还注意到,在终端行末尾添加更多文本会导致与上面 80 列描述的效果非常相似的问题。问题是:是否bash
错误地处理新行或“太长” PS1
?
谢谢。
更新
这个问题并不完全重复为什么当我浏览历史记录时,我的 bash 提示符会出现问题?。经过与@AdamKatz的一些讨论后,似乎零长度输出转义\[
并且']
仅当它们字面地放入PS1
字符串中时才起作用,但是当从函数返回时它们似乎不起作用,导致在终端上出现未转义。
答案1
对于多行提示(包括换行时,包括来自命令的提示),您需要将颜色代码括在转义的方括号中(喜欢\[$color\]
)。
此示例是绿色的,user@hostname:workingdir $
然后恢复为无色:
PS1='\[\e[1;32m\]\u@\h:\w \$\[\e[0;0m\]'
如果您看到文字\[
或[
出现在提示中,则它可能在被解释为提示扩展之前从 扩展\[
为。[
在这种情况下,\001
不断\[
尝试\002
,\]
你应该就可以开始了。如果您没有运气\e
,请尝试\033
一下。这些八进制代码更易于移植,因为它们会通过(类似的程序sed
不会尝试转义或解释它们)。