我想在Linux终端中编写自动完成代码。代码应该如下工作。
它有一个字符串列表(例如“你好”,“你好”,“你好吗”,“再见”,“很棒”,......)。
在终端中,用户将开始输入,当有一些匹配的可能性时,他会获得可能的字符串的提示,他可以从中选择(与vim editor或google incremental search类似)。
e.g。他开始输入“h”并得到提示
H “ELLO”
_“我”
_“你是不是”
更好的是,如果它不仅从头开始,而且从字符串的任意部分完成单词。
感谢您的建议。
答案 0 :(得分:44)
(我知道这不是你要求的,但是)如果你对 TAB 上出现的自动完成/建议感到满意(在很多shell中使用) ),然后您可以使用readline模块快速启动并运行。
以下是基于Doug Hellmann's PyMOTW writeup on readline的简单示例。
import readline
class MyCompleter(object): # Custom completer
def __init__(self, options):
self.options = sorted(options)
def complete(self, text, state):
if state == 0: # on first trigger, build possible matches
if text: # cache matches (entries that start with entered text)
self.matches = [s for s in self.options
if s and s.startswith(text)]
else: # no text entered, all matches possible
self.matches = self.options[:]
# return match indexed by state
try:
return self.matches[state]
except IndexError:
return None
completer = MyCompleter(["hello", "hi", "how are you", "goodbye", "great"])
readline.set_completer(completer.complete)
readline.parse_and_bind('tab: complete')
input = raw_input("Input: ")
print "You entered", input
这会导致以下行为(<TAB>
表示正在按下的Tab键):
Input: <TAB><TAB>
goodbye great hello hi how are you
Input: h<TAB><TAB>
hello hi how are you
Input: ho<TAB>ow are you
在输入的最后一行( H O TAB )中,只有一个可能匹配且整个句子“你好吗”已自动完成。
查看链接的文章,了解有关readline
。
“更好的是,如果它不仅从一开始就完成单词......从字符串的任意部分完成。”
这可以通过简单地修改完成函数中的匹配条件来实现,即。从:
self.matches = [s for s in self.options
if s and s.startswith(text)]
类似于:
self.matches = [s for s in self.options
if text in s]
这会给您以下行为:
Input: <TAB><TAB>
goodbye great hello hi how are you
Input: o<TAB><TAB>
goodbye hello how are you
创建用于滚动/搜索的伪菜单的一种简单方法是将关键字加载到历史缓冲区中。然后,您可以使用向上/向下箭头键滚动条目,也可以使用 Ctrl + R 执行反向搜索。
要尝试此操作,请进行以下更改:
keywords = ["hello", "hi", "how are you", "goodbye", "great"]
completer = MyCompleter(keywords)
readline.set_completer(completer.complete)
readline.parse_and_bind('tab: complete')
for kw in keywords:
readline.add_history(kw)
input = raw_input("Input: ")
print "You entered", input
运行脚本时,请尝试键入 Ctrl + r ,然后键入 a 。这将返回包含“a”的第一个匹配。再次输入 Ctrl + r 以进行下一场比赛。要选择条目,请按 ENTER 。
还可以尝试使用向上/向下键滚动关键字。
答案 1 :(得分:6)
我想你需要得到一个用户按下的键。
你可以用这样的方法实现它(不按回车):
import termios, os, sys
def getkey():
fd = sys.stdin.fileno()
old = termios.tcgetattr(fd)
new = termios.tcgetattr(fd)
new[3] = new[3] & ~termios.ICANON & ~termios.ECHO
new[6][termios.VMIN] = 1
new[6][termios.VTIME] = 0
termios.tcsetattr(fd, termios.TCSANOW, new)
c = None
try:
c = os.read(fd, 1)
finally:
termios.tcsetattr(fd, termios.TCSAFLUSH, old)
return c
然后,如果此键是Tab键(例如,您需要实现的那些键),则向用户显示所有可能性。如果是其他任何键,请在stdout上打印。
哦,当然,只要用户点击进入,你就需要在一段时间内使用getkey()循环。你也可以得到一个像raw_input这样的方法,当你点击标签时,它会逐个符号地显示整个单词,或显示所有可能性。
至少那是项目,你可以先开始。如果你遇到任何其他问题,那就写下来吧。
编辑1:
get_word方法如下所示:
def get_word():
s = ""
while True:
a = getkey()
if a == "\n":
break
elif a == "\t":
print "all possibilities"
else:
s += a
return s
word = get_word()
print word
我现在遇到的问题是显示标志的方式,您刚刚输入时没有任何进入和空格,print a
和print a,
都有。
答案 2 :(得分:4)
要在Python shell中启用自动填充,请输入:
import rlcompleter, readline
readline.parse_and_bind('tab:complete')
答案 3 :(得分:2)
步骤:
通过以下命令在主目录中创建文件.pythonrc:
vi .pythonrc
输入此内容:
import rlcompleter, readline
readline.parse_and_bind('tab:complete')
关闭文件
现在运行
echo "export PYTHONSTARTUP=~/.pythonrc" >> ~/.bashrc
重新启动终端
答案 4 :(得分:2)
您可能想签出快速自动完成功能:https://github.com/seperman/fast-autocomplete
它具有演示模式,您可以在键入时输入并获取结果:https://zepworks.com/posts/you-autocomplete-me/#part-6-demo
它非常易于使用:
>>> from fast_autocomplete import AutoComplete
>>> words = {'book': {}, 'burrito': {}, 'pizza': {}, 'pasta':{}}
>>> autocomplete = AutoComplete(words=words)
>>> autocomplete.search(word='b', max_cost=3, size=3)
[['book'], ['burrito']]
>>> autocomplete.search(word='bu', max_cost=3, size=3)
[['burrito']]
>>> autocomplete.search(word='barrito', max_cost=3, size=3) # mis-spelling
[['burrito']]
免责声明:我写了快速自动完成。
答案 5 :(得分:1)
对于那些(像我一样)最终在这里搜索解释器中的自动完成的人:
这涉及创建文件.pythonrc
,修改.bashrc
和每次启动Python解释器时必须导入的import sys
。
我想知道后者是否可以自动获得更多胜利。