如何获取 PS1 产生的提示的屏幕宽度(带或不带@P)?

如何获取 PS1 产生的提示的屏幕宽度(带或不带@P)?

例如,假设PS1具有如下所示的值:

'\w (\[\e[32m\]${__git_ps1_branch_name}\[\e[0m\] \[\e[31m\]*\[\e[31m\]%\[\e[0m\]>)\$ '

...哪里__git_ps1_branch_name有一些字符串,例如masteror feature123

问:我正在寻找一种方法来计算将从如上所示的提示bash中生成的提示的屏幕宽度(以字符数为单位) 。PS1


最新版本将bash表达式扩展${PS1@P}为通过将上面提示规范的元素替换为其最终显示值而获得的字符串。 (\w例如,将被替换为当前目录的路径,并将${__git_ps1_branch_name}被替换为变量中包含的字符串__git_ps1_branch_name等)但这还不足以解决问题。

更具体地说,如果我们设置:

EXPANDED_PS1="${PS1@P}"

...表达式${#EXPANDED_PS1}(即 中的字符数$EXPANDED_PS1)产生的数字是明显更大比 bash 生成的提示符的屏幕宽度要大$PS1。多余的部分来自为显示的提示赋予颜色的转义序列。

任何状况之下,我是对适用于不支持的 bash 版本的解决方案感兴趣@P

答案1

没有支持就@P很难。问题是,你需要扩展PS1,但该功能是私有的,所以你不能直接使用它。尽管如此,还是有一些非常好的尝试这个问题

如果您确实有支持,@P那么这可能对您有用:

$ echo -ne "\n${PS1@P}\033[6n";read -e -s -d R cnt;cnt=$((${cnt#;} - 1));echo $cnt

PS1首先发送一个新行和扩展的字符串。这意味着光标现在将位于该列PS1 的长度 + 1

然后是 ANSI 转义码设备状态报告(CSI6n) 已发送。终端回复:

通过发送 ESC[n;mR,其中 n 是行,m 是列,报告光标位置 (CPR)。)

该值从标准输入读取并放入cnt

它'hackish,仅适用于 ANSI 终端,但它似乎可以工作。请注意,如果扩展长度大于终端的宽度,则该列将不会显示 的长度PS1。其他进程的输出也可能是一个问题。

相关内容