Как повторно использовать дополнения из PathCompleter в prompt_toolkit
Я создаю инструмент REPL для своего проекта, который (упрощенный для ясности) либо непосредственно выполняет введенные команды, либо (если введена команда ".x some/path/to/file") читает и выполняет их из файла. Мой вопрос связан с автозаполнением пользовательского ввода (с использованием prompt_toolkit).
У меня есть что-то вроде (минимальный исполняемый пример):
import prompt_toolkit
from prompt_toolkit.completion import Completer, Completion
from prompt_toolkit.document import Document
from prompt_toolkit.contrib.completers import PathCompleter
class CommandCompleter(Completer):
def __init__(self):
self.path_completer = PathCompleter()
self.commands = [".x", "command1", "command2"]
def get_completions(self, document, complete_event):
if document.text.startswith(".x "):
sub_doc = Document(document.text[3:])
yield from (Completion(cmd.text, -document.cursor_position)
# ???????? ?????????????????????????
for cmd
in self.path_completer.get_completions(sub_doc, complete_event))
# ???????
else:
yield from (Completion(cmd, -document.cursor_position)
for cmd in self.commands
if cmd.startswith(document.text))
if __name__ == "__main__":
while True:
other_args = {}
input = prompt_toolkit.prompt(">>> ", completer=CommandCompleter(), **other_args)
# Do something with input (omitted)
Вторая ветвь if (для команд) работает правильно, но я не знаю, как правильно вызвать PathCompleter.get_completions()
метод и реконструировать Completion
объекты из его результата (где???) в первой ветви. Хитрость в том, что я использую завершение только для части ввода, а различные подстроки, расчеты положения и т. Д. (Пока) не привели к удовлетворительному поведению (то есть предложили пути и построили правильную строку ввода).
Я определенно продолжу поиск, но если кто-нибудь знает, как переписать это, это было бы очень полезно.
Замечания: yield from self.path_completer.get_completions(document, complete_event)
будет использоваться, если весь вход будет только путь (и это работает правильно).
1 ответ
Вероятно, следующее должно это исправить:
sub_doc = Document(document.text[3:])
yield from (Completion(completion.text, completion.start_position, display=completion.display)
for completion
in self.path_completer.get_completions(sub_doc, complete_event))
completion.text
содержит текст, который будет вставлен;completion.start_position
содержит место, куда будет вставляться текст относительно позиции курсора (в этом конкретном примере мы можем взять значение из вложенного завершителя).completion.display
это значение, отображаемое во всплывающем меню. (В этом случае все имя файла, а не только вставленная строка.
Не стесняйтесь, чтобы открыть вопрос GitHub, если у вас есть еще вопросы.