Привет кодерам и смелым пользователям GNU-readline,
Несколько месяцев назад я начал использовать модуль readline Python (2.7.1) для подобного оболочке приложения, которое я написал. Приложение не имеет ничего общего с файлами и файловыми системами - это индивидуальное решение для проприетарного программного обеспечения для управления.
Вчера я обнаружил, что определенный текст вызывает непредвиденное поведение автозаполнения, и не нашел способа решить эту проблему в документации . Я отчаянно прошу вашей помощи здесь. Я начну с примера и последую за фрагментом кода, который воспроизводит нежелательное поведение.
Предоставление значений для автозаполнения:
aaa0 aaa1 aaa2 bbb_0 bbb_1 bbb_2
ccc-0 ccc-1 ccc-2 ddd?0 ddd?1 ddd?2
... тогда неожиданное поведение выглядит следующим образом (каждое действие сопровождается результирующим выводом, а знак «|» представляет курсор):
- Введите 'b'.
Input> b|
- Нажмите TAB (который в моей конфигурации связан с действием автозавершения).
Input> bbb_|
- Нажмите TAB еще раз. Ваш текст останется прежним, но вы получите следующую подсказку:
bbb_0 bbb_1 bbb_2<br>
Input> bbb_|
- Введите '0' и нажмите клавишу TAB.
bbb_0 bbb_1 bbb_2<br>
Input> bbb_0 |
Обратите внимание на пробел между символом «0» и курсором (приведенный ниже фрагмент кода должен это объяснить).
Пока все хорошо, и попытка того же с 'a' приведет к аналогичному выводу, только без подчеркивания (aaa0, aaa1, aaa2).
- Начните сначала и введите 'c'.
Input> c
- Нажмите клавишу TAB.
Input> ccc-
- Снова нажмите TAB.
aaa0 aaa1 aaa2 bbb_0 bbb_1 bbb_2 ccc-0 ccc-1 ccc-2 ddd?0 ddd?1 ddd?2<br>
Input> ccc-|
Это первая половина моей проблемы. Отображаются все значения, а не только значения, начинающиеся с 'ccc -'.
- Введите '0' и нажмите клавишу TAB.
aaa0 aaa1 aaa2 bbb_0 bbb_1 bbb_2 ccc-0 ccc-1 ccc-2 ddd?0 ddd?1 ddd?2<br>
Input> ccc-0|
Вот вторая половина моей проблемы, видите ли, между символом «0» и курсором нет пробела (опять же, фрагмент ниже должен объяснить, почему должен быть пробел). Фактически, нажатие клавиши TAB не изменяет текст и не отображает подсказки, и последующие нажатия клавиши TAB ведут себя так же.
На практике то, что происходит на шаге 7, является недоразумением . Readline «ошибается» символом тире «-» для разделителя слов (и то же самое касается символа вопросительного знака «?», Если вы пытаетесь автоматически завершить «ddd?»; Другие распространенные разделители слов, например: пробел, табуляция, '='). Итак, поскольку текущий буфер строки заканчивается разделителем слов, тогда пришло время для нового слова, верно? Следовательно, на шаге 7 (вот где мы находимся) все значения отображаются после нажатия клавиши TAB.
На шаге 8, когда строка выглядит так: "Input> ccc-0|
", нажатие клавиши TAB не дает никакого эффекта, потому что тире, будучи разделителем слов, разделяет строку на два слова: 'ccc' и '0'. Таким образом, слово, которое должно быть завершено, равно «0», но, увы, ни одно из возможных значений не начинается с «0», так что никакого эффекта.
Теперь, к сожалению, здесь нет правильного или неправильного. Например, в моем приложении знак равенства '=' на самом деле является разделителем слов, а тире '-' - нет. Полагаю, это должно быть вопросом конфигурации, но я не нашел способа настроить, какие символы разделяют слова. Вот с чем мне нужна помощь.
Я человек своего слова, поэтому вот фрагмент кода, который я обещал:
import readline
values = ['aaa0', 'aaa1', 'aaa2', 'bbb_0', 'bbb_1', 'bbb_2',
'ccc-0', 'ccc-1', 'ccc-2', 'ddd?0', 'ddd?1', 'ddd?2']
def complete(text, state):
matches = [v for v in values if v.startswith(text)]
if len(matches) == 1 and matches[0] == text:
# Add space if the current text is the same as the only match
return "{} ".format(matches[0]) if state == 0 else None
if state >= len(matches):
return None
return matches[state]
readline.set_completer(complete)
for line in ("tab: complete", "set show-all-if-unmodified on"):
readline.parse_and_bind(line)
raw_input("Input> ")
Мальчики и девочки, пожалуйста - помогите! Я обещаю быть очень благодарным и даже вернуть одолжение. )
Большое спасибо заранее,
Амнон Г