提问者:小点点

Readline被ANSI转义序列混淆


我正在编写一个Python脚本,有时需要用户输入。我在MacOS Sierra上使用bash。

为了接收输入,我写了以下内容:

import readline  # gnureadline 6.3.8

START = '\033[91m\033[1m'
END = '\033[0m'

response = raw_input(START + 'Enter text: ' + END)

我正在使用STARTEND中的ANSI转义序列从视觉上区分脚本的提示和用户的文本输入。

不幸的是,一旦我开始输入文本,程序就会丢失用户输入文本的起始位置。下面的第一克拉是CTRLA现在映射到的地方,第二克拉是CTRLE带我去的地方。箭头键类似地相信用户输入的开始和结束是如所示的偏移。

Enter text: hello my name is             
                         ^               ^  

我尝试了一些方法来调试这个。

>

如果我只使用箭头键,而从不使用类似于CTRLACTRLE,选项箭头之类的东西来在字符串中导航,这将按预期工作。也就是说,考虑到用户输入的字符串的长度和复杂性,仅使用箭头键在字符串中移动对用户来说是痛苦的。

最重要的是,如果我根本不使用STARTEND,这是完美的。也就是说,脚本的可用性下降了——很难从这个脚本完整版本中所有其他文本中挑选出提示。

是否有一些技巧可以让我使用ANSI转义序列格式化提示,而不破坏用户使用CTRLACTRLE和选项箭头导航的能力?非常感谢。


共3个答案

匿名用户

Readline希望\001\002作为不可见字符周围的标记:

import readline  # gnureadline 6.3.8

START = '\001\033[91m\033[1m\002'
END = '\001\033[0m\002'

response = raw_input(START + 'Enter text: ' + END)

ANSI转义序列前缀为\001,后缀为\002,GNU readline将知道在确定提示字符串的长度时应该排除这些字符。

匿名用户

将提示和请求输入分别打印到两个命令中。

Python 3。十、

print(START + 'Enter text: ' + END, end='')
response = input()

Python 2。十、

import sys

# Use sys.stdout.write to avoid printing a trailing newline.
sys.stdout.write(START + 'Enter text: ' + END)
response = raw_input()

匿名用户

就我而言,公认的答案没有奏效。

我从

START = '\x1b[7m\x1b[37m' # white on black
END = '\x1b[0m'  # reset
response = input(START + 'QUERY ' + END)

这同样导致了

QUERY hello my name is hello my name is
              ^                                ^
              hello my name is hello my name is

使用上面的解决方案,

print(START + 'QUERY ' + END, end='')
response = input()

导致考虑从一开始就开始生产线

QUERY hello my name is hello my name is
^                                ^
hello my name is hello my name is

可能是由于输入(“”)长度为0个字符。

知道这些控制字符被计为偏移量,我们可以使用它们再次创建偏移量。

我的文本,QUERY有6个字符长,因此我可以使用

print(START + 'QUERY ' + END, end='')
response = input('\033[D\033[C')

因为光标向前、向后、'\033'、'['、'D''\033'、'['、'C'正在欺骗读线偏移6个字符。

QUERY hello my name is hello my name is
\[D\[C^                                ^
      hello my name is hello my name is