readline — Интерфейс к GNU readline


Модуль readline определяет ряд функций для облегчения завершения и чтения/записи файлов истории из интерпретатора Python. Этот модуль можно использовать напрямую или через модуль rlcompleter, который поддерживает завершение идентификаторов Python в интерактивном приглашении. Настройки, сделанные с помощью этого модуля, влияют на поведение как интерактивного приглашения интерпретатора, так и подсказок, предлагаемых встроенной функцией input().

Привязки клавиш для readline можно настроить с помощью файла инициализации, обычно .inputrc в вашем домашнем каталоге. См. Init файл Readline в руководстве GNU Readline для получения информации о формате и допустимых конструкциях этого файла, а также о возможностях библиотеки Readline в целом.

Примечание

Базовый API библиотеки Readline может быть реализован библиотекой libedit вместо библиотеки readline GNU. В macOS модуль readline определяет, какая библиотека используется во время выполнения.

Файл конфигурации для libedit отличается от файла конфигурации GNU readline. Если вы программно загружаете строки конфигурации, вы можете проверить текст «libedit» в readline.__doc__, чтобы различать GNU readline и libedit.

Если вы используете эмуляцию readline editline/libedit в macOS, файл инициализации, расположенный в вашем домашнем каталоге, будет с именем .editrc. Например, следующий контент в ~/.editrc включит vi сочетания клавиш и TAB завершение:

python:bind -v
python:bind ^I rl_complete

Init файл

Следующие функции относятся к файлу инициализации и пользовательской конфигурации:

readline.parse_and_bind(string)

Выполнить строку инициализации, указанную в аргументе string. Вызывает rl_parse_and_bind() в базовой библиотеке.

readline.read_init_file([filename])

Выполнить файл инициализации readline. Имя файла по умолчанию — это последнее использованное имя файла. Вызывает rl_read_init_file() в базовой библиотеке.

Буфер строки

Следующие функции работают с строковым буфером:

readline.get_line_buffer()

Возвращает текущее содержимое строкового буфера (rl_line_buffer в базовой библиотеке).

readline.insert_text(string)

Вставить текст в строковый буфер в позиции курсора. Вызывает rl_insert_text() в базовой библиотеке, но игнорирует возвращаемое значение.

readline.redisplay()

Изменить то, что отображается на экране, чтобы отразить текущее содержимое строкового буфера. Вызывает rl_redisplay() в базовой библиотеке.

Файл истории

Следующие функции работают с файлом истории:

readline.read_history_file([filename])

Загрузить файл истории readline и добавить его в список истории. Имя файла по умолчанию — ~/.history. Вызывает read_history() в базовой библиотеке.

readline.write_history_file([filename])

Сохранить список истории в файл истории readline, перезаписав любой существующий файл. Имя файла по умолчанию — ~/.history. Вызывает write_history() в базовой библиотеке.

readline.append_history_file(nelements[, filename])

Добавить в файл последние записи истории nelements. Имя файла по умолчанию — ~/.history. Файл должен уже существовать. Вызывает append_history() в базовой библиотеке. Эта функция существует только в том случае, если Python был скомпилирован для версии библиотеки, которая её поддерживает.

Добавлено в версии 3.5.

readline.get_history_length()
readline.set_history_length(length)

Установить или вернуть желаемое количество строк для сохранения в файле истории. Функция write_history_file() использует это значение для усечения файла истории, вызывая history_truncate_file() в базовой библиотеке. Отрицательные значения подразумевают неограниченный размер файла истории.

Список истории

Следующие функции работают с глобальным списком истории:

readline.clear_history()

Очистить текущую историю. Вызывает clear_history() в базовой библиотеке. Функция Python существует только в том случае, если Python был скомпилирован для версии библиотеки, которая её поддерживает.

readline.get_current_history_length()

Возвращает количество элементов, находящихся в настоящее время в истории. (Это отличается от get_history_length(), которая возвращает максимальное количество строк, которые будут записаны в файл истории.)

readline.get_history_item(index)

Возвращает текущее содержимое элемента истории в index. Индекс элемента основан на единице. Вызывает history_get() в базовой библиотеке.

readline.remove_history_item(pos)

Удаляет из истории элемент истории, указанный по его позиции. Позиция отсчитывается от нуля. Вызывает remove_history() в базовой библиотеке.

readline.replace_history_item(pos, line)

Заменяет элемент истории, указанный его позицией, на line. Позиция отсчитывается от нуля. Вызывает replace_history_entry() в базовой библиотеке.

readline.add_history(line)

Добавляет line в буфер истории, как если бы это была последняя введённая строка. Вызывает add_history() в базовой библиотеке.

readline.set_auto_history(enabled)

Включение или отключение автоматических вызовов add_history() при чтении ввода через readline. Аргумент enabled должен быть логическим значением, которое, когда истинно, включает автоматическую историю, а когда ложно, отключает автоматическую историю.

Добавлено в версии 3.6.

Детали реализации CPython: Автоматическая история включена по умолчанию, и её изменения не сохраняются в течение нескольких сеансов.

Хуки запуска

readline.set_startup_hook([function])

Установить или удалить функцию, вызываемую обратным вызовом rl_startup_hook базовой библиотеки. Если указан function, он будет использоваться как новая хук функция; если пропущена или None, любая уже установленная функция удаляется. Хук вызывается без аргументов непосредственно перед тем, как readline напечатает первое приглашение.

readline.set_pre_input_hook([function])

Установить или удалить функцию, вызываемую обратным вызовом rl_pre_input_hook базовой библиотеки. Если указан function, он будет использоваться как новая хук функция; если пропущена или None, любая уже установленная функция удаляется. Хук вызывается без аргументов после того, как первая подсказка была напечатана, и непосредственно перед тем, как readline начнёт чтение входных символов. Эта функция существует только в том случае, если Python был скомпилирован для версии библиотеки, которая её поддерживает.

Завершение

Следующие функции относятся к реализации пользовательской функции завершения слова. Обычно для этого используется клавиша Tab, и она может предлагать и автоматически завершать вводимое слово. По умолчанию Readline настроен на использование rlcompleter для заполнения идентификаторов Python для интерактивного интерпретатора. Если модуль readline должен использоваться с пользовательским дополнением, следует установить другое множество разделителей слов.

readline.set_completer([function])

Установить или удалить функцию завершения. Если указан function, он будет использоваться как новая функция завершения; если он пропущен или None, любая уже установленная функция завершения удаляется. Функция завершения вызывается как function(text, state) для state в 0, 1, 2, …, пока она не вернёт нестроковое значение. Она должна вернуть следующее возможное завершение, начиная с text.

Установленная функция завершения вызывается обратным вызовом entry_func, переданным в rl_completion_matches() в базовой библиотеке. Строка text поступает от первого параметра к обратному вызову rl_attempted_completion_function базовой библиотеки.

readline.get_completer()

Получить функцию завершения или None, если функция завершения не задана.

readline.get_completion_type()

Получить тип попытки завершения. Это возвращает переменную rl_completion_type в базовой библиотеке в виде целого числа.

readline.get_begidx()
readline.get_endidx()

Получить начальный или конечный индекс области завершения. Эти индексы являются аргументами start и end, переданными функции обратного вызова rl_attempted_completion_function базовой библиотеки.

readline.set_completer_delims(string)
readline.get_completer_delims()

Установить или получить разделители слов для завершения. Они определяют начало слова, которое будет считаться завершением (пространство завершения). Эти функции обращаются к переменной rl_completer_word_break_characters в базовой библиотеке.

readline.set_completion_display_matches_hook([function])

Установить или удалить функцию отображения завершения. Если указан function, он будет использоваться как новая функция отображения завершения; если пропущен или None, любая уже установленная функция отображения завершения удаляется. Это устанавливает или очищает обратный вызов rl_completion_display_matches_hook в базовой библиотеке. Функция отображения завершения вызывается как function(substitution, [matches], longest_match_length) один раз, когда необходимо отобразить совпадения.

Пример

В следующем примере показано, как использовать функции чтения и записи истории модуля readline для автоматической загрузки и сохранения файла истории с именем .python_history из домашнего каталога пользователя. Приведённый ниже код обычно выполняется автоматически во время интерактивных сеансов из пользовательского файла PYTHONSTARTUP.

import atexit
import os
import readline

histfile = os.path.join(os.path.expanduser("~"), ".python_history")
try:
    readline.read_history_file(histfile)
    # по умолчанию длина историяи равна -1 (бесконечная), которая может стать неуправляемой
    readline.set_history_length(1000)
except FileNotFoundError:
    pass

atexit.register(readline.write_history_file, histfile)

Этот код фактически запускается автоматически при запуске Python в интерактивном режиме (см. Конфигурация Readline).

В следующем примере достигается та же цель, но поддерживаются параллельные интерактивные сеансы, только путём добавления новой истории.

import atexit
import os
import readline
histfile = os.path.join(os.path.expanduser("~"), ".python_history")

try:
    readline.read_history_file(histfile)
    h_len = readline.get_current_history_length()
except FileNotFoundError:
    open(histfile, 'wb').close()
    h_len = 0

def save(prev_h_len, histfile):
    new_h_len = readline.get_current_history_length()
    readline.set_history_length(1000)
    readline.append_history_file(new_h_len - prev_h_len, histfile)
atexit.register(save, h_len, histfile)

В следующем примере класс code.InteractiveConsole расширяется для поддержки сохранения/восстановления истории.

import atexit
import code
import os
import readline

class HistoryConsole(code.InteractiveConsole):
    def __init__(self, locals=None, filename="<console>",
                 histfile=os.path.expanduser("~/.console-history")):
        code.InteractiveConsole.__init__(self, locals, filename)
        self.init_history(histfile)

    def init_history(self, histfile):
        readline.parse_and_bind("tab: complete")
        if hasattr(readline, "read_history_file"):
            try:
                readline.read_history_file(histfile)
            except FileNotFoundError:
                pass
            atexit.register(self.save_history, histfile)

    def save_history(self, histfile):
        readline.set_history_length(1000)
        readline.write_history_file(histfile)