readline смущен escape-последовательностями ANSI - PullRequest
0 голосов
/ 22 мая 2018

Я работаю над скриптом Python, который иногда требует ввода данных пользователем.Я использую bash на macOS Sierra.

Чтобы получить ввод, я написал следующее:

import readline  # gnureadline 6.3.8

START = '\033[91m\033[1m'
END = '\033[0m'

response = raw_input(START + 'Enter text: ' + END)

Я использую escape-последовательности ANSI в START и ENDчтобы визуально отличить подсказку скрипта от текстовой записи пользователя.

К сожалению, как только я начинаю набирать текст, программа теряет отслеживание того, где на самом деле находится начало введенного пользователем текста.Первый карат ниже - это то, куда CTRL A теперь отображается, а второй - куда CTRL E .Клавиши со стрелками также считают, что начало и конец пользовательского ввода смещены, как показано на рисунке.

Enter text: hello my name is             
                         ^               ^  

Я попытался отладить несколько вещей.

  1. Я пыталсядобавление новой строки между приглашением и вводом текста, но это только ухудшило смещение.

  2. Если I только , используйте клавиши со стрелками и никогда ничего, например CTRL A , CTRL E , опция-стрелка для навигации по строке, это работает, как и ожидалось.Тем не менее, учитывая длину и сложность строк, которые вводит пользователь, использование только клавиш со стрелками для перемещения по строке будет болезненным для пользователя.

  3. Наиболее существенно, если явообще не используйте START и END, это прекрасно работает.Тем не менее, удобство использования скрипта падает - трудно выбрать подсказки из всего другого текста, проходящего в полной версии этого скрипта.

Есть ли какая-то хитрость длячтобы я мог использовать escape-последовательности ANSI для форматирования приглашения, не мешая пользователю перемещаться с помощью CTRL A , CTRL E , а опция-стрелка?Спасибо!

Ответы [ 3 ]

0 голосов
/ 06 августа 2018

В моем случае принятый ответ не сработал.

Я начал с

START = '\x1b[7m\x1b[37m' # white on black
END = '\x1b[0m'  # reset
response = input(START + 'QUERY ' + END)

, что также привело к

QUERY hello my name is hello my name is
              ^                                ^
              hello my name is hello my name is

Использование решения выше,

print(START + 'QUERY ' + END, end='')
response = input()

привело к тому, что строка начиналась с начала

QUERY hello my name is hello my name is
^                                ^
hello my name is hello my name is

, вероятно, из-за того, что input("") имеет длину 0 символов.

Зная, чтоэти управляющие символы учитываются как смещение, мы можем просто использовать их для повторного создания смещения.

Мой текст, QUERY имеет длину 6 символов, поэтому я мог бы использовать

print(START + 'QUERY ' + END, end='')
response = input('\033[D\033[C')

, потому что Курсор Вперед, Курсор Назад '\033', '[', 'D', '\033', '[', 'C' обманывает readline для смещения 6 символов.

QUERY hello my name is hello my name is
\[D\[C^                                ^
      hello my name is hello my name is
0 голосов
/ 20 апреля 2019

Readline ожидает \001 и \002 в качестве маркеров вокруг невидимых символов:

import readline  # gnureadline 6.3.8

START = '\001\033[91m\033[1m\002'
END = '\001\033[0m\002'

response = raw_input(START + 'Enter text: ' + END)

С escape-последовательностями ANSI с префиксом \001 и суффиксом \002 GNU readline будет знать, что эти символыследует исключить при определении длины строки подсказки.

0 голосов
/ 22 мая 2018

Раздельная печать приглашения и запроса ввода двух команд.

Python 3.x

print(START + 'Enter text: ' + END, end='')
response = input()

Python 2.x

import sys

# Use sys.stdout.write to avoid printing a trailing newline.
sys.stdout.write(START + 'Enter text: ' + END)
response = raw_input()
...