Emacs终端Bash(PS1)提示符重复

4

这个问题有点复杂,但是我尝试解释一下!最近我更新了我的bash提示符,采用了该帖子中显示的漂亮版本: Bash: custom PS1 with nice working directory path。 相关的bash代码(来自该帖子)如下:

# define the awk script using heredoc notation for easy modification
MYPSDIR_AWK=$(cat << 'EOF'
BEGIN { FS = OFS = "/" }
{ 
   if (length($0) > 16 && NF > 4)
      print $1,$2,".." NF-4 "..",$(NF-1),$NF
   else
      print $0
}
EOF
)

# my replacement for \w prompt expansion
export MYPSDIR='$(echo -n "${PWD/#$HOME/~}" | awk "$MYPSDIR_AWK")'

# the fancy colorized prompt: [0 user@host ~]%
# return code is in green, user@host is in bold/white
export PS1='[\[\033[1;32m\]$?\[\033[0;0m\] \[\033[0;1m\]\u@\h\[\033[0;0m\] $(eval "echo ${MYPSDIR}")]% '

# set x/ssh window title as well
export PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME%%.*} $(eval "echo ${MYPSDIR}")\007"'

这个提示大致看起来像这样(在非emacs终端中):

[0 user@host ~/my_dir]%

上面的“0”是绿色的,“user@host”是粗体。(请注意,“0”可以是各种数字,并表示上一个命令的返回值。)

我遇到的问题是特定于在emacs内运行的shell(并且它发生在emacs中大多数终端交互的变体中:'term'、'ansi-term'、'shell'和'eshell')。提示符在emacs终端中出现两次(并且略微损坏),如下所示:

0;user@host ~/my_dir[0 user@host ~/my_dir]%

“第二个”版本的提示,从“[”开始到结尾看起来很好。 但是前面的文本没有任何样式(即没有绿色和加粗)。 因此,emacs 必须将提示的某些部分解释为输入,我的猜测是与提示中的“0”和“user@host”部分相关的颜色或加粗转义指示符?

有人知道如何告诉 emacs 正确地解释转义吗? 或者,如何修改提示设置命令,使得既可以在 emacs 中使用,又可以在非 emacs 终端中工作且不会出现问题? 甚至还可能有另一种选择:如何添加一个测试终端类型的功能(在 emacs 中为 'eterm-color'),并使用经过修改的字符串使其适用于 emacs?


如果禁用PROMPT_COMMAND,这会停止吗? - Etan Reisner
好的,我会尝试添加一个钩子来清除那个环境变量,以便于shell使用。(或者就不要使用窗口标题更新功能了。)再次感谢! - mmuurr
可能有办法让emacs理解该控制序列,但我甚至不知道从何入手。我使用vim。=) - Etan Reisner
请参考类似问题的答案“在ansi-term中使用ssh时,Shell提示符重复”的链接:https://dev59.com/FnTYa4cB1Zd3GeqPtFHi#17598138 - Alex Vorobiev
2个回答

5
错误来自于export PROMPT_COMMAND=...语句。
你可以通过检查是否在emacs中运行shell来避免读取此配置。这里环境变量INSIDE_EMACS非常方便。根据Emacs手册(Sect. 32.7):
“Emacs将version设置为环境变量INSIDE_EMACS的子shell,comint为‘version’,其中version是Emacs版本(例如‘24.1’)。程序可以检查此变量以确定它们是否在Emacs子shell中运行”
在你的例子中,当你不在emacs中时,你希望执行 export PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME%%.*} $(eval "echo ${MYPSDIR}")\007",否则你会得到这个讨厌的“双提示”。下面的条件语句可以帮助你。
if [ -z "$INSIDE_EMACS" ];
 then
  export PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME%%.*} $(eval "echo ${MYPSDIR}")\007"'
 else
  export PROMPT_COMMAND=''
fi

它检查您是否不在emacs中,仅在此情况下将PROMPT_COMMAND变量设置为所需值。

0
额外的显示是来自于PROMPT_COMMAND变量的内容。emacs似乎不理解OSC 0标题设置的xterm转义序列,因此会打印出输出内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接