Python + приглашение bash: как распечатать обертки для вычисления ширины?

1

Я написал сценарий Python для замены "powerline" в качестве решения для терминала для себя здесь: https://github.com/diogobaeder/dotfiles/blob/master/.bash_prompt.py

Тогда все, что я делаю, это определить подсказку из вывода этого скрипта:

# in my ~/.bashrc
export PS1="\$(python ~/.bash_prompt.py)"

Сам скрипт отлично работает, я получаю приглашение командной строки, которое я хочу; Однако, поскольку для стилей, которые я там помещаю, нет обертывания, терминал (неважно, какая программа GUI-терминала я использую) не правильно вычисляет ширину приглашения, и когда я ввожу символы после подсказки, она не завершает их на новую строку сначала, полностью перезаписывая приглашение.

Теперь я знаю, что при стилизации моего запроса bash мне нужно избегать кодов стиля с помощью \[ и \] так что bash учитывает, что они являются escape-последовательностями и правильно вычисляет ширину. Однако, если я поместил их в качестве оболочек для своих стилей в свой скрипт Python (см. esc_start и esc_end), я не могу заставить их правильно оценивать bash как "escape escape-последовательности", вместо этого я получаю печатные квадратные скобки с буквами. Если я затем выйду на Python и обратную косую черту (\\[ и \\]), тогда я получаю невыпущенные литералы (\[ и \]). Кажется, что Bash полностью игнорирует их как escape-последовательности для вычисления ширины подсказки.

Если, однако, я удаляю обратную косую черту в моей команде PS1 ($(python ~/.bash_prompt.py) вместо \$(python ~/.bash_prompt.py)), а затем помещая \[ и \] качестве escape-последовательностей в моем Python (как esc_start и esc_end), тогда bash считает их правильными экранами и заканчивает завершающие строки, как ожидалось (т. esc_start esc_end через правую границу, она завершает линию, как ожидалось). Однако проблема с этим заключается в том, что удаление этой обратной косой черты из моего определения PS1 в .bashrc заставляет сценарий запускаться только один раз за сеанс терминала, а не для каждой строки подсказки - так, например, если я в рабочем дереве Git и я перехожу из одной ветки в другую, она не показывает новую ветвь, как только команда заканчивается, вместо нее отображается старая ветка.

Позвольте мне привести несколько примеров того, что я имею в виду, что вы можете попробовать в своем собственном .bashrc без моего сценария Python:

PS1="\[\033[31m\]\u@\h\[\033[0m\]$ " # This wraps lines correctly
PS1="\033[31m\u@\h\033[0m$ " # This makes the line overwrite the prompt

Итак, любые идеи о том, как справиться с bash и заставить его правильно понимать последовательности \[ и \], когда они печатаются с помощью скрипта Python, сохраняя при этом скрипт для каждой командной строки? Или, если это ограничение в bash, есть ли другой способ заставить его обернуть линию, когда она достигнет правой границы окна терминала?

Спасибо! Диого

[EDIT] Решение (спасибо, Гриша Левит!):

Это моя линия bashrc:

PROMPT_COMMAND='PS1="$(python ~/.bash_prompt.py)"'

И я снова добавил escapes (\[ и \]) к моему скрипту, и теперь он работает отлично! :-)

  • 0
    Трудно сказать, не видя сценарий Python или его вывод.
Теги:
colors
prompt

1 ответ

1
Лучший ответ

Сначала Bash интерпретирует escape-последовательности в $PS1 и только потом обрабатывает подстановку команд и т.д.

Bash позволяет настраивать эти строки, вставляя несколько специальных символов с обратным слэшем, которые декодируются следующим образом [...] После того, как строка декодируется, она расширяется посредством расширения параметров, замены команд, арифметического расширения и удаления цитат [...]

- Справочное руководство Bash: управление запросом

Это означает, что любые специальные последовательности, напечатанные вашей командой, не будут интерпретироваться как цвета и т.д. Решение заключается в использовании $PROMPT_COMMAND для изменения значения $PS1, например:

PROMPT_COMMAND='PS1=$(python ~/.bash_prompt.py)'
  • 0
    Чувак, это сработало без нареканий! Большое спасибо, чувак! :-)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню