使用 Conda 环境前缀更新 Xterm 标题栏

使用 Conda 环境前缀更新 Xterm 标题栏

我想更新我的 gnome 终端选项卡以指示该终端中处于活动状态的 conda 环境。我通常会同时激活许多选项卡和一些环境,因此找到正确的选项卡很令人沮丧。

Conda 在通过切换到环境时更新提示(通过在提示前添加环境前缀),source activate environment-prefix并在使用 停用环境时恢复提示conda deactivate

但是,似乎没有办法强制 conda 更新xterm 标题栏当它更新提示时。似乎没有办法编辑更新后会保留的激活脚本。此外,遵循 conda 和 activate 脚本的逻辑并没有提供一个明显的位置来添加此功能(至少我可以弄清楚)。我找不到的 2017 年的一篇旧帖子提到了这个问题,但编辑激活脚本的解决方案似乎不再适用,我的搜索没有找到解决方案。

我想要一个能够自动工作并且不会改变提示的其他部分的解决方案,可以在我的所有终端/shell(在主题主机上)中使用,并且可以与 conda 无缝工作。

答案1

我最终做的是在 .bashrc 文件中创建一个函数。该函数运行正常的 conda activate 脚本,该脚本照常将环境添加到提示中。然后该函数编辑提示变量以将环境添加到 Xterm 标题栏中。

好处是正常的 conda activate 脚本运行时不会改变,并且conda deactivate脚本会撤消效果,甚至 Xterm 标题栏中的更改也是如此。

以下是 .bashrc 文件中的函数定义,下面是有关其设计的更多详细信息。

# function to replace a call to the activate script in conda and set 
#+ Xterm title bar to include environment by
#+ replacing "source activate" with the following "activate" function

activate () {
# run the normal conda activate script first
#+ passing all arguments
    . activate $* 

# the activate script creates some Anaconda variables, including
# CONDA_PROMPT_MODIFIER which has the environment prefix in parens
# create a couple of temporary variables

    preX='\\[\\e\]0\;'
    Xrepl="\[\e]0;${CONDA_PROMPT_MODIFIER} "
# no need to test for xterm, since no match if no xterm title bar
# no need to check for no matches, since PS1 will remain unchanged

    PS1=${PS1/${preX}/${Xrepl}}
}

要使用该功能并激活给定环境,只需键入 activate env-name。此功能反映了 Anaconda 的 Windows 安装,其中环境是通过运行脚本直接激活的(无需“获取”它)。

逐行:

. activate $*

此行运行 Anaconda 默认安装的激活脚本。 Anaconda 还将自己的 bin 目录添加到路径中,因此无需完全限定该位置。 $* 包含所有函数参数并将它们发送到激活脚本。

preX='\\[\\e\]0\;'

该变量保存在提示变量 (PS1) 中定义 Xterm 标题栏开头的转义序列。我从 Xterm 标题栏获得的转义序列第 6.3 章。 Xterm 标题栏操作。我从中获得的有关提示变量及其组件的详细信息Bash 提示符 HOWTO。此外,这个论坛帖子最初是一个很好的资源:在终端命令提示符中更改用户、主机、目录信息的颜色

变量定义中的单引号可防止字符被解释一次,但反斜杠、方括号和分号需要转义,因为它们在下面的搜索表达式中进行计算。我必须通过尝试和(很多)错误来解决这个问题。我知道这是 bash 更复杂的方面之一。

Xrepl="\[\e]0;${CONDA_PROMPT_MODIFIER} "

该变量保存转义序列的替换。由于转义序列本身被替换(见下文),因此需要将其包含在替换文本中,但由于某种原因,不会评估此变量,因此preX不需要额外的转义。

CONDA_PROMPT_MODIFIER变量由激活脚本插入到环境中,并在括号之间包含环境前缀。

PS1=${PS1/${preX}/${Xrepl}}

最后,这里的工作就完成了。这就是一个“简单”bash 字符串操作。在变量preX内搜索变量内容PS1。如果找到它们,它们将被替换为变量的内容Xrepl。如果未找到,则不会对提示进行任何更改。这种效果使得该函数不必确保终端是 xterm。

令人惊奇的是,当conda deactivate运行时,它会删除提示中的前缀以及 Xterm 标题栏中插入的环境。我想这是因为它只是缓存了原始提示,但我不确定。

我希望这可以帮助别人。这对我来说是一次学习经历,因为我对 bash 和脚本的功能不是很熟悉。更不用说提示的详细信息以及用它可以完成的所有操作。

相关内容