Иногда невозможно или неудобно заранее создать список (alist) или массив символов (obarray), содержащий все предполагаемые возможные варианты дополнения. В таком случае вы можете передать собственную функцию для вычисления дополнения заданной строки. Это называется программируемым дополнением. Emacs использует программируемое дополнение при дополнении имён файлов (см. Дополнение имён файлов), а также во многих других случаях.
Чтобы использовать эту возможность, передайте функцию в качестве аргумента collection
в completing-read. Функция
completing-read организует передачу вашей функции дополнения
в try-completion, all-completions и другие базовые
функции дополнения, которые затем позволят вашей функции выполнять
всю работу.
Функция дополнения должна принимать три аргумента:
nil, если фильтрация не требуется. Функция должна вызывать предикат для каждого
возможного совпадения и игнорировать совпадение, если предикат возвращает
nil.
nilЗадаёт операцию try-completion. Функция должна возвращать
nil, если совпадений нет; t,
если указанная строка является уникальным и точным совпадением; и
наибольший общий префикс всех совпадений в противном случае.
tЗадаёт операцию all-completions. Функция
должна возвращать список всех возможных дополнений указанной
строки.
lambdaЗадаёт операцию test-completion. Функция
должна возвращать t, если указанная строка является точным совпадением для
какого-либо варианта дополнения; в противном случае — nil.
(boundaries . suffix)Задаёт операцию completion-boundaries. Функция
должна возвращать (boundaries start . end), где
start — позиция начала границы в указанной строке,
а end — позиция конца границы в
suffix.
Если программа на Lisp возвращает нетривиальные границы, она должна убедиться, что
операция all-completions согласована с ними.
Дополнения, возвращаемые all-completions, должны относиться только к
той части префикса и суффикса, которая охватывается границами
дополнения. См. Базовые функции дополнения для точной ожидаемой семантики
границ дополнения.
metadataЗапрашивает информацию о состоянии текущего
дополнения. Возвращаемое значение должно иметь вид
(metadata . alist), где alist — это список ассоциаций, элементы
которого описаны ниже.
Если флаг имеет любое другое значение, функция дополнения должна возвращать
nil.
Ниже приведён список записей метаданных, которые функция дополнения
может возвращать в ответ на аргумент-флаг metadata:
categoryЗначение должно быть символом, описывающим, какой тип текста
пытается дополнить функция. Если символ совпадает с одним
из ключей в completion-category-overrides, обычное
поведение дополнения переопределяется. См. Переменные для дополнения.
annotation-functionЗначение должно быть функцией для аннотирования дополнений.
Функция должна принимать один аргумент string (возможный
вариант дополнения) и возвращать строку, которая отображается после
строки дополнения string в буфере *Completions*.
Если эта функция не устанавливает собственный шрифт для строки-суффикса аннотации,
к этой строке по умолчанию применяется лицо completions-annotations.
affixation-functionЗначение должно быть функцией для добавления префиксов и суффиксов к
дополнениям. Функция должна принимать один аргумент
completions (список возможных дополнений) и возвращать
такой список completions, где каждый элемент содержит список
из трёх элементов: дополнение, префикс, отображаемый перед
строкой дополнения в буфере *Completions*, и
суффикс, отображаемый после строки дополнения. Эта функция
имеет приоритет над annotation-function.
group-functionЗначение должно быть функцией для группировки кандидатов дополнения.
Функция должна принимать два аргумента: completion (кандидат
дополнения) и transform (логический флаг). Если
transform равен nil, функция должна возвращать заголовок
группы, к которой принадлежит кандидат. Возвращаемый заголовок
также может быть nil. В противном случае функция должна возвращать
преобразованного кандидата. Преобразование может, например, удалять
избыточный префикс, который отображается в заголовке группы.
display-sort-functionЗначение должно быть функцией для сортировки дополнений. Функция должна принимать один аргумент (список строк дополнений) и возвращать отсортированный список строк дополнений. Допускается изменять входной список деструктивно.
cycle-sort-functionЗначение должно быть функцией для сортировки дополнений, когда
completion-cycle-threshold не равен nil, и пользователь
перебирает варианты дополнений по циклу. См. Параметры дополнения в Руководстве GNU Emacs. Список аргументов и возвращаемое значение
такие же, как для display-sort-function.
Эта функция является удобным способом написания функции, которая может действовать как
программируемая функция дополнения. Аргумент function должен
быть функцией, принимающей один аргумент (строку) и возвращающей
таблицу дополнений (см. Базовые функции дополнения), содержащую все
возможные дополнения. Таблица, возвращаемая function, может также
содержать элементы, не соответствующие строковому аргументу; они
автоматически отфильтровываются completion-table-dynamic. В
частности, function может игнорировать свой аргумент и возвращать полный
список всех возможных дополнений. Можно рассматривать
completion-table-dynamic как преобразователь между function
и интерфейсом программируемых функций дополнения.
Если необязательный аргумент switch-buffer не равен nil, и
дополнение выполняется в минибуфере, function будет
вызвана с текущим буфером, установленным в буфер, из которого был вызван
минибуфер.
Возвращаемое значение completion-table-dynamic — это функция,
которую можно использовать в качестве 2-го аргумента для try-completion и
all-completions. Обратите внимание, что эта функция всегда будет возвращать
пустые метаданные и тривиальные границы.
Это обёртка для completion-table-dynamic, которая сохраняет
последнюю пару аргумент-результат. Это означает, что множественные обращения с
одним и тем же аргументом вызывают function только один раз.
Это может быть полезно, если задействована медленная операция, например вызов внешнего процесса.