在绘制ZSH提示时获取当前光标位置

时间:2017-05-11 09:11:40

标签: command-prompt zsh ansi-escape zsh-zle

我试图从绘制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"

但是,如果我启动一个干净的zsh -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访问该信息。

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

1 个答案:

答案 0 :(得分:2)

直接从/dev/tty读取似乎主要起作用,但它仍然会吞噬在prompt_fn开头和read命令之间输入的任何输入。如果prompt_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` '