shell 如何在zsh widget中的提示符下面打印彩色文本?

rsl1atfo  于 2023-03-24  发布在  Shell
关注(0)|答案(1)|浏览(120)

此问题的答案有资格获得+400声望bounty。赏金宽限期已结束。Poma希望引起更多关注此问题。
我想创建一个绑定到热键的小部件,它在提示符下以富文本形式打印当前命令描述,然后在按下一个键后将其擦除。

widget() {
  zle -R "ls - list files"
  read -k 1
}
zle -N widget
bindkey '\eg' widget

但是zle -R只能打印纯文本,它甚至不支持换行符。我想像^[[31mls^[[00m - list files一样打印带有颜色和换行符的文本。
我可以使用哪些方法来做到这一点?
只是将它打印到一个常规的标准输出,然后初始化一个新的提示符,对于我的用例来说,这是一个糟糕的用户界面,这是一个不受欢迎的解决方案。
我希望它出现在提示符下面,并且与zsh-autocomplete,ctrl+R或fzf类似。输出没有任何复杂的交互,它只出现在热键上,然后在按键时消失。
zsh-autocomplete repo也做了类似的事情,但我不知道它是如何做到的。

i5desfxk

i5desfxk1#

当你使用zle -R时,你最终会在zsh内部调用这个函数。-R之后的第一个参数存储在statusline中。在这里检查并删除任何会意外修改屏幕的字符。所以邮件列表question from 2011今天仍然存在。
在回顾了zsh-autocomplete中的钩子和代码后,我现在明白了这是通过在zsh中使用内置的颜色突出显示支持,同时积极使用autocomplete来实现的。
因为你只是希望有一个键绑定来显示状态行并等待击键,你需要(用C)写一个模块来显示当前的BUFFER并等待击键。这将需要你跟踪光标位置并保持zsh所期望的相同状态。
example module是一个开始,您需要使用zsh编译它,因为构建脚本使用从模块的.mdd创建.mdh/.pro文件所需的工具构建所有模块。
下面是一个更新的小部件,演示了各种选项:

widget() {
  autoload -Uz colors && colors
  PREDISPLAY="PRE:"
  POSTDISPLAY="${fg[red]}POST$reset_color"
  zle -R "$BUFFER" "${fg[red]}line below$reset_color"
  print "${fg[red]}print$reset_color"
  read -k 1
}
zle -N widget

注意,你不能控制状态行的显示,它已经删除了所有的特殊字符。print正确地允许特殊字符,但只在输入行上(不在状态行上)。PRE/POST也只在输入行上工作,并且也被剥夺了特殊字符。
我可以使用哪些方法来做到这一点?

  • 编写自己的模块。这是最好的方法。
  • 你可以使用print来按照你的意愿给它上色,但是你仍然需要确保屏幕的位置保持在zsh期望的位置。

相关问题