Как исправить вычисление столбца в Python readline, если использовать цветную подсказку
Я использую стандартные советы для настройки интерактивного сеанса Python:
$ cat ~/.bashrc
export PYTHONSTARTUP=~/.pystartup
$ cat ~/.pystartup
import os
import sys
import atexit
import readline
import rlcompleter
historyPath = os.path.expanduser("~/.pyhistory")
def save_history(historyPath=historyPath):
import readline
readline.write_history_file(historyPath)
if os.path.exists(historyPath):
readline.read_history_file(historyPath)
term_with_colors = ['xterm', 'xterm-color', 'xterm-256color', 'linux', 'screen', 'screen-256color', 'screen-bce']
if os.environ.get('TERM') in term_with_colors:
green='\033[32m'
red='\033[31m'
reset='\033[0m'
sys.ps1 = red + '>>> ' + reset
sys.ps2 = green + '... ' + reset
del term_with_colors
atexit.register(save_history)
del os, sys, atexit, readline, rlcompleter, save_history, historyPath
Теперь я получаю контекстное завершение и цветную подсказку.
Проблема возникает из-за цветовой подсказки - когда я вызываю history-search-backward (нажатием UP) в интерактивном сеансе Python, Readline учитывает escape-последовательности терминала, поэтому позиция курсора неверно рассчитывается и текст отображается неправильно.
На странице руководства Bash эта проблема упоминается и исправляется специальными маркерами:
\[ begin a sequence of non-printing characters,
which could be used to embed a
terminal control sequence into the prompt
\] end a sequence of non-printing characters
Как исправить эту проблему для подсказки Python?
Ответы
Ответ 1
Я открываю info readline и обнаружил:
-- Function: int rl_expand_prompt (char *prompt)
Expand any special character sequences in PROMPT and set up the
local Readline prompt redisplay variables. This function is
called by `readline()'. It may also be called to expand the
primary prompt if the `rl_on_new_line_with_prompt()' function or
`rl_already_prompted' variable is used. It returns the number of
visible characters on the last line of the (possibly multi-line)
prompt. Applications may indicate that the prompt contains
characters that take up no physical screen space when displayed by
bracketing a sequence of such characters with the special markers
`RL_PROMPT_START_IGNORE' and `RL_PROMPT_END_IGNORE' (declared in
`readline.h'. This may be used to embed terminal-specific escape
sequences in prompts.
Как говорят текст, я ищу определение RL_PROMPT_START_IGNORE и RL_PROMPT_END_IGNORE в readline.h и нашел следующее:
/* Definitions available for use by readline clients. */
#define RL_PROMPT_START_IGNORE '\001'
#define RL_PROMPT_END_IGNORE '\002'
Итак, я поместил соответствующие изменения в мой ~/.pystartup:
green='\001\033[32m\002'
red='\001\033[31m\002'
reset='\001\033[0m\002'
и теперь все работает нормально!!!
Ответ 2
Для лучшего опыта работы с оболочкой Python я бы порекомендовал вам использовать ipython или bpython.