4

我正在尝试从绘制 ZSH shell 提示符的函数中将当前光标位置(当前行号和列)读入变量中。我的目标是在提示下方显示内容,前提是有足够的空行不会导致额外的滚动。

在交互式 shell 中,我可以使用以下命令:

echo -ne "\033[6n"
read -t 1 -s -d 'R' line
line="${line##*\[}"
line="${line%;*}"
echo "XX $line XX"
# Prints: XX 2 XX"

但是,如果我启动 cleanzsh -f并将其放入呈现提示时执行的函数中,它将停止工作:

setopt prompt_subst
prompt_fn(){
  echo -ne "\033[6n"
  read -t 1 -s -d 'R' line
  line="${line##*\[}"
  line="${line%;*}"
  echo "XX $line XX"
}
PROMPT='`prompt_fn` '

终端返回的 ANSI 转义序列被附加到当前命令(就像我在键盘上键入它一样),但不会被read -t 1 -s -d 'R' line上面的命令吞噬。我怀疑 ZSH 在绘制提示时禁用了对 STDIN 的访问,但我不知道如何临时重新获得对它的访问(在绘制提示之前键入的正常键盘击键,或者在绘制提示的十分之一秒内不应该是截获),或如何使用 ZLE 访问该信息。

编辑:如果用户在显示提示之前已经键入了命令的开头,则不应丢弃该输入。到目前为止,我找到的解决方案(请参阅下面我自己的答案)不幸地读取并删除了这些字符。这令人沮丧,因为当我打开一个新的终端窗口并立即开始输入时,在提示出现之前输入的字符将被丢弃。

4

2 回答 2

4

直接读取似乎大部分都有效,但它仍然会吞噬在开头和命令/dev/tty之间输入的任何输入。如果在到达该点之前做一些工作,它可能会导致一些用户输入被丢弃。希望有人会提出更好的解决方案。prompt_fnreadprompt_fn

setopt prompt_subst
prompt_fn(){
  echo -ne "\033[6n" > /dev/tty
  read -t 1 -s -d 'R' line < /dev/tty
  line="${line##*\[}"
  line="${line%;*}"
  echo "XX $line XX"
}
PROMPT='`prompt_fn` '
于 2017-05-11T09:39:08.193 回答
1

也许您想查看minibuffer这些文档的基础:

http://zsh.sourceforge.net/Guide/zshguide04.html

`minibuffer' 是另一个 Emacs 概念。它是出现在命令行下方的提示,供您输入编辑器本身所需的一些编辑。

我在 zsh 插件中使用它来打印光标下命令的帮助。我只显示文本,但你应该可以用它做其他事情。

作弊缓冲区示例

您还可以在此处找到有关 zsh 小部件的一些信息

这可能是相关的:

缓冲线(整数)

当前在屏幕上显示的编辑缓冲区所需的屏幕行数(即上次重新显示后对前面的参数没有任何更改);只读。

于 2018-05-11T05:30:54.240 回答