readline 被 ANSI 转义序列混淆
readline confused by ANSI escape sequences
我正在开发一个 Python 脚本,该脚本有时需要用户输入。我在 macOS Sierra 上使用 bash。
为了接收输入,我写了以下内容:
import readline # gnureadline 6.3.8
START = '3[91m3[1m'
END = '3[0m'
response = raw_input(START + 'Enter text: ' + END)
我在 START
和 END
中使用 ANSI 转义序列来从视觉上区分脚本的提示和用户的文本输入。
不幸的是,一旦我开始输入文本,程序就无法跟踪用户输入文本的实际开始位置。下面的第一个克拉是 CTRLA 现在映射到的位置,第二个是 CTRL[= 的位置35=]E带我。箭头键同样认为用户输入的开始和结束是偏移的,如图所示。
Enter text: hello my name is
^ ^
我尝试了一些调试方法。
我尝试在提示符和文本输入之间添加一个换行符,但这只会使偏移更糟。
如果我只使用方向键而不是CTRLA, CTRLE, option-arrow 来浏览字符串,这按预期工作。也就是说,考虑到用户输入的字符串的长度和复杂性,仅使用箭头键在字符串中移动对用户来说会很痛苦。
最重要的是,如果我根本不使用 START
和 END
,这将完美运行。也就是说,脚本的可用性下降了——很难从完整版脚本的所有其他文本中找出提示。
我有什么技巧可以使用 ANSI 转义序列来格式化提示,而不会破坏用户使用 CTRLA 进行导航的能力、CTRLE 和选项箭头?谢谢!
将提示和要求输入分开打印到两个命令中。
Python 3.x
print(START + 'Enter text: ' + END, end='')
response = input()
Python 2.x
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
可能是因为 input("")
的长度为 0 个字符。
知道那些控制字符被算作偏移量,我们可以使用它们再次创建偏移量。
我的文本 QUERY
有 6 个字符,所以我可以使用
print(START + 'QUERY ' + END, end='')
response = input('3[D3[C')
因为Cursor Forward, Cursor Back
'3', '[', 'D'
、'3', '[', 'C'
正在欺骗 readline
偏移 6 个字符。
QUERY hello my name is hello my name is
\[D\[C^ ^
hello my name is hello my name is
Readline 期望 [=11=]1
和 [=12=]2
作为不可见字符周围的标记:
import readline # gnureadline 6.3.8
START = '[=10=]13[91m3[1m[=10=]2'
END = '[=10=]13[0m[=10=]2'
response = raw_input(START + 'Enter text: ' + END)
使用 ANSI 转义序列以 [=11=]1
为前缀并以 [=12=]2
为后缀,GNU readline 将知道在确定提示字符串的长度时应排除这些字符。
我正在开发一个 Python 脚本,该脚本有时需要用户输入。我在 macOS Sierra 上使用 bash。
为了接收输入,我写了以下内容:
import readline # gnureadline 6.3.8
START = '3[91m3[1m'
END = '3[0m'
response = raw_input(START + 'Enter text: ' + END)
我在 START
和 END
中使用 ANSI 转义序列来从视觉上区分脚本的提示和用户的文本输入。
不幸的是,一旦我开始输入文本,程序就无法跟踪用户输入文本的实际开始位置。下面的第一个克拉是 CTRLA 现在映射到的位置,第二个是 CTRL[= 的位置35=]E带我。箭头键同样认为用户输入的开始和结束是偏移的,如图所示。
Enter text: hello my name is
^ ^
我尝试了一些调试方法。
我尝试在提示符和文本输入之间添加一个换行符,但这只会使偏移更糟。
如果我只使用方向键而不是CTRLA, CTRLE, option-arrow 来浏览字符串,这按预期工作。也就是说,考虑到用户输入的字符串的长度和复杂性,仅使用箭头键在字符串中移动对用户来说会很痛苦。
最重要的是,如果我根本不使用
START
和END
,这将完美运行。也就是说,脚本的可用性下降了——很难从完整版脚本的所有其他文本中找出提示。
我有什么技巧可以使用 ANSI 转义序列来格式化提示,而不会破坏用户使用 CTRLA 进行导航的能力、CTRLE 和选项箭头?谢谢!
将提示和要求输入分开打印到两个命令中。
Python 3.x
print(START + 'Enter text: ' + END, end='')
response = input()
Python 2.x
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
可能是因为 input("")
的长度为 0 个字符。
知道那些控制字符被算作偏移量,我们可以使用它们再次创建偏移量。
我的文本 QUERY
有 6 个字符,所以我可以使用
print(START + 'QUERY ' + END, end='')
response = input('3[D3[C')
因为Cursor Forward, Cursor Back
'3', '[', 'D'
、'3', '[', 'C'
正在欺骗 readline
偏移 6 个字符。
QUERY hello my name is hello my name is
\[D\[C^ ^
hello my name is hello my name is
Readline 期望 [=11=]1
和 [=12=]2
作为不可见字符周围的标记:
import readline # gnureadline 6.3.8
START = '[=10=]13[91m3[1m[=10=]2'
END = '[=10=]13[0m[=10=]2'
response = raw_input(START + 'Enter text: ' + END)
使用 ANSI 转义序列以 [=11=]1
为前缀并以 [=12=]2
为后缀,GNU readline 将知道在确定提示字符串的长度时应排除这些字符。