Python3实现基于索引的动态逐词自动补全功能相关问题咨询
逐词独立逻辑动态补全工具实现方案
你需要的效果本质是上下文感知的分层补全,每一个位置的补全候选集完全由前面已输入的所有token决定,你之前用到的库本身都支持该能力,只需自定义对应补全回调逻辑即可,不需要额外引入其他依赖。
方案1:基于prompt_toolkit实现(首选)
prompt_toolkit原生支持高度自定义的补全逻辑,你只需要基于已有的补全器接口开发分层匹配规则即可:
- 第一步:抽象你的补全规则为层级映射表,每个路径对应当前位置的补全候选集,支持动态修改更新索引
- 第二步:自定义继承
Completer类,重写get_completions方法,每次触发补全时先拆分当前输入的token,按已输入的前序token匹配到对应层级的候选集,过滤后返回 - 示例实现代码:
from prompt_toolkit import prompt from prompt_toolkit.completion import Completer, Completion # 可动态更新的层级补全规则表 completion_rules = { "root": ["use", "set", "run", "exit"], "use": ["stackoverflow", "github", "local_db"], "set": ["proxy", "timeout", "user"], "set.proxy": ["http://127.0.0.1:7890", "http://127.0.0.1:1080"], "use.stackoverflow": ["search", "browse", "answer"] } class HierarchicalCompleter(Completer): def get_completions(self, document, complete_event): tokens = document.text_before_cursor.strip().split() # 无输入时返回根级候选 if not tokens: for item in completion_rules["root"]: yield Completion(item, start_position=0) return # 构造当前层级匹配key current_level = ".".join(tokens[:-1]) if len(tokens) > 1 else tokens[0] prefix = tokens[-1] # 匹配当前位置候选 for item in completion_rules.get(current_level, []): if item.startswith(prefix): yield Completion(item, start_position=-len(prefix)) if __name__ == "__main__": while True: user_input = prompt("PROMPT> ", completer=HierarchicalCompleter()) if user_input.strip() == "exit": break
方案2:基于readline实现
如果你需要兼容更轻量的原生readline环境,仅需重写补全回调函数即可实现同等效果:
- 核心逻辑和上述方案一致,通过
readline.get_line_buffer()获取当前全量输入内容,拆分token后按层级匹配候选集 - 示例实现代码:
import readline completion_rules = { "root": ["use", "set", "run", "exit"], "use": ["stackoverflow", "github", "local_db"], "set": ["proxy", "timeout", "user"] } def complete(text, state): buffer = readline.get_line_buffer() tokens = buffer.split() # 根级补全逻辑 if len(tokens) == 0 or (len(tokens) == 1 and not buffer.endswith(" ")): options = [i for i in completion_rules["root"] if i.startswith(text)] else: current_level = tokens[0] options = [i for i in completion_rules.get(current_level, []) if i.startswith(text)] return options[state] if state < len(options) else None readline.set_completer(complete) readline.parse_and_bind('tab: complete') while True: user_input = input("PROMPT> ") if user_input.strip() == "exit": break
扩展说明
- 如需支持N层补全逻辑,只需扩展
completion_rules的层级映射即可,例如三层补全可以用"use.stackoverflow.search"作为key匹配第四位的候选集 - 你提到的Empire工具的核心实现逻辑和上述方案完全一致,它将补全规则抽象为命令树结构,每个命令节点存储对应的子命令候选集,触发补全时沿着已输入的token遍历到对应节点,返回子节点列表作为补全候选
- 如需支持动态索引更新,仅需在运行时修改
completion_rules映射表即可,不需要重启服务进程
内容的提问来源于stack exchange,提问作者Crazy Mike
相关产品推荐
相关产品推荐

