我正在尝试编写一个功能,以便在用户按下标签按钮时显示自定义视图。显然“set_completion_display_matches_hook”功能是我需要的,我可以显示自定义视图,但问题是我必须按Enter才能再次获得提示。
Python2中的解决方案似乎是(solution here):
def match_display_hook(self, substitution, matches, longest_match_length):
print ''
for match in matches:
print match
print self.prompt.rstrip(),
print readline.get_line_buffer(),
readline.redisplay()
但它不适用于Python3。我做了这些语法更改:
def match_display_hook(self, substitution, matches, longest_match_length):
print('\n----------------------------------------------\n')
for match in matches:
print(match)
print(self.prompt.rstrip() + readline.get_line_buffer())
readline.redisplay()
有什么想法吗?
答案 0 :(得分:1)
redisplay()
函数
void
rl_redisplay (void)
更改屏幕上显示的内容以反映rl_line_buffer的当前内容。
在您的示例中,您已写入stdout
,但没有更改该缓冲区。
按照other answer中所述进行打印和冲洗应该可以。
但是,您将遇到的一个问题是光标位置。假设您有这种情况:
$ cmd some_file ^ +---- User has back-tracked here and want to insert an option. <TAB> completion with print and flush will put cursor at end of `some_file' and the line will get an extra 15 spaces after that ...
要纠正这种情况,首先要获取光标位置,然后使用ANSI序列重新定位光标。
buf = readline.get_line_buffer()
x = readline.get_endidx()
print(self.prompt + buf, end = '')
if x < len(buf):
""" Set cursor at old column position """
print("\r\033[%dC" % (x + len(self.prompt)), end = '')
sys.stdout.flush()
现在,如果prompt
本身具有ANSI序列,那么您当然会遇到另一个问题。通常为彩色等。然后,您将无法使用len(prompt)
,而必须找到已打印的/可见的长度。
一个人必须在其他地方使用打开和关闭字节,通常分别为\0x01
和\0x02
。
所以通常会得到:
prompt = '\001\033[31;1m\002VISIBLE_TEXT\001\033[0m\002 '
代替:
prompt = '\033[31;1mVISIBLE_TEXT\033[0m '
有了这些警卫,应该很容易地去除可见的文本。
通常类似:
clean_prompt = re.sub(r'\001[^\002]*\002', '', prompt))
缓存该长度并在手动打印readline时使用。请注意,当您手动使用护罩时,还必须卸下护罩-如挂钩功能一样。 (但是input(prompt)
答案 1 :(得分:0)
首先,Python 2代码使用逗号来保留未完成的行。在Python 3中,它使用end
关键字完成:
print(self.prompt.rstrip(), readline.get_line_buffer(), sep='', end='')
然后,需要刷新才能实际显示未完成的行(由于行缓冲):
sys.stdout.flush()
似乎不需要redisplay()
来电。
最终代码:
def match_display_hook(self, substitution, matches, longest_match_length):
print()
for match in matches:
print(match)
print(self.prompt.rstrip(), readline.get_line_buffer(), sep='', end='')
sys.stdout.flush()
答案 2 :(得分:0)
这个对我有用,用于重新显示替换,并且显示python3的比赛结束:
def match_display_hook(self, substitution, matches, longest_match_length):
print("")
for match in matches:
print(match)
print("")
sys.stdout.write(substitution)
sys.stdout.flush()
return None
,而以前使用打印提示的人没有。 (没有找到问题的根本)