21.6.1 Функции базового автодополнения

Следующие функции автодополнения сами по себе не имеют отношения к минибуферам. Мы описываем их здесь, чтобы они находились рядом с более высокоуровневыми функциями автодополнения, которые используют минибуфер.

Функция: try-completion коллекция строк и опциональный предикат

Эта функция возвращает самую длинную общую подстроку всех возможных дополнений string в collection.

collection называется таблицей дополнений. Ее значение должно быть списком строк или ячеек cons, obarray, хеш-таблицей или функцией автодополнения.

try-completion сравнивает string с каждой из разрешенных дополнений, указанных таблицей дополнений. Если ни одно разрешенное дополнение не совпадает, она возвращает nil. Если есть только одно совпадающее дополнение, и совпадение точное, она возвращает t. В противном случае она возвращает самую длинную начальную последовательность, общую для всех возможных совпадающих дополнений.

Если collection — это список, разрешенные дополнения указываются элементами списка, каждый из которых должен быть либо строкой, либо ячейкой cons, чей CAR является либо строкой, либо символом (символ преобразуется в строку с помощью symbol-name). Если список содержит элементы другого типа, они игнорируются.

Если collection — это obarray (см. Создание и интернирование символов), имена всех символов в obarray составляют набор разрешенных дополнений.

Если collection — это хеш-таблица, то ключи, которые являются строками или символами, являются возможными дополнениями. Другие ключи игнорируются.

Вы также можете использовать функцию в качестве collection. Тогда функция полностью отвечает за выполнение автодополнения; try-completion возвращает то, что возвращает эта функция. Функция вызывается с тремя аргументами: string, predicate и nil (третий аргумент нужен, чтобы одна и та же функция могла использоваться в all-completions и выполнять соответствующее действие в обоих случаях). См. Программируемое автодополнение.

Если аргумент predicate не равен nil, то он должен быть функцией с одним аргументом, если только collection не является хеш-таблицей, в этом случае это должна быть функция с двумя аргументами. Она используется для проверки каждого возможного совпадения, и совпадение принимается только в том случае, если predicate возвращает не-nil. Аргумент, переданный predicate, — это либо строка, либо ячейка cons (чей CAR является строкой) из alist, либо символ (не имя символа) из obarray. Если collection — это хеш-таблица, predicate вызывается с двумя аргументами: строковым ключом и соответствующим значением.

Кроме того, чтобы быть приемлемым, дополнение также должно соответствовать всем регулярным выражениям в completion-regexp-list. (Если collection — это функция, то эта функция должна обрабатывать completion-regexp-list сама.)

В первом из следующих примеров строка ‘foo’ совпадает с тремя CAR из alist. Все совпадения начинаются с символов ‘fooba’, поэтому это и есть результат. Во втором примере существует только одно возможное совпадение, и оно точное, поэтому возвращаемое значение — t.

(try-completion
 "foo"
 '(("foobar1" 1) ("barfoo" 2) ("foobaz" 3) ("foobar2" 4)))
     ⇒ "fooba"

(try-completion "foo" '(("barfoo" 2) ("foo" 3)))
     ⇒ t

В следующем примере множество символов начинаются с символов ‘forw’, и все они начинаются со слова ‘forward’. В большинстве символов за этим следует ‘-’, но не во всех, поэтому можно дополнить не более чем до ‘forward’.

(try-completion "forw" obarray)
     ⇒ "forward"

Наконец, в следующем примере только два из трех возможных совпадений проходят предикат test (строка ‘foobaz’ слишком коротка). Оба из них начинаются со строки ‘foobar’.

(defun test (s)
  (> (length (car s)) 6))
     ⇒ test
(try-completion
 "foo"
 '(("foobar1" 1) ("barfoo" 2) ("foobaz" 3) ("foobar2" 4))
 'test)
     ⇒ "foobar"
Функция: all-completions string collection &optional predicate

Эта функция возвращает список всех возможных дополнений string. Аргументы этой функции те же, что и у try-completion, и она использует completion-regexp-list так же, как и try-completion.

Если collection — это функция, она вызывается с тремя аргументами: string, predicate и t; тогда all-completions возвращает то, что возвращает функция. См. Программируемое автодополнение.

Вот пример с использованием функции test, показанной в примере для try-completion:

(defun test (s)
  (> (length (car s)) 6))
     ⇒ test

(all-completions
 "foo"
 '(("foobar1" 1) ("barfoo" 2) ("foobaz" 3) ("foobar2" 4))
 'test)
     ⇒ ("foobar1" "foobar2")
Функция: test-completion string collection &optional predicate

Эта функция возвращает не-nil, если string является допустимой альтернативой дополнения, указанной collection и predicate. Аргументы те же, что и в try-completion. Например, если collection — это список строк, это истинно, если string присутствует в списке, и predicate удовлетворен.

Эта функция использует completion-regexp-list так же, как и try-completion.

Если predicate не равен nil, и если collection содержит несколько строк, равных друг другу, согласно compare-strings в соответствии с completion-ignore-case, то predicate должен принять либо все, либо ни одно из них. В противном случае возвращаемое значение test-completion по сути непредсказуемо.

Если collection — это функция, она вызывается с тремя аргументами, значениями string, predicate и lambda; что бы она ни вернула, test-completion возвращает в ответ.

Функция: completion-boundaries string collection predicate suffix

Эта функция возвращает границы поля, на котором collection будет работать, предполагая, что string содержит текст до точки, а suffix содержит текст после точки.

Обычно автодополнение работает со всей строкой, поэтому для всех обычных коллекций она всегда вернет (0 . (length suffix)). Но более сложное автодополнение, например, автодополнение в файлах, выполняется по одному полю за раз. Например, автодополнение "/usr/sh" будет включать "/usr/share/", но не "/usr/share/doc", даже если "/usr/share/doc" существует. Также all-completions для "/usr/sh" не будет включать "/usr/share/", а только "share/". Таким образом, если string — это "/usr/sh", а suffix — "e/doc", completion-boundaries вернет (5 . 1), что говорит нам о том, что collection будет возвращать информацию о дополнениях, относящуюся только к области после "/usr/" и до "/doc". try-completion не зависит от нетривиальных границ; например, try-completion для "/usr/sh" все еще может вернуть "/usr/share/", а не "share/".

Если вы сохраняете alist дополнений в переменной, вы должны пометить переменную как рискованную, присвоив ей свойство risky-local-variable не-nil. См. Локальные переменные файла.

Переменная: completion-ignore-case

Если значение этой переменной не равно nil, регистр не считается значимым при автодополнении. В read-file-name эта переменная переопределяется read-file-name-completion-ignore-case (см. Чтение имен файлов); в read-buffer она переопределяется read-buffer-completion-ignore-case (см. Функции автодополнения высокого уровня).

Переменная: completion-regexp-list

Это список регулярных выражений. Функции автодополнения считают дополнение допустимым только в том случае, если оно соответствует всем регулярным выражениям в этом списке, с использованием case-fold-search (см. Поиск и регистр), привязанному к значению completion-ignore-case.

Не устанавливайте эту переменную в не-nil значение глобально, так как это небезопасно и, вероятно, вызовет ошибки в командах автодополнения. Эта переменная должна быть установлена только с помощью let в не-nil значениях вокруг вызовов базовых функций автодополнения: try-completion, test-completion и all-completions.

Макрос: lazy-completion-table var fun

Этот макрос предоставляет способ инициализации переменной var как коллекции для автодополнения в ленивом режиме, не вычисляя ее фактическое содержимое до тех пор, пока оно не понадобится. Вы используете этот макрос, чтобы получить значение, которое вы сохраняете в var. Фактическое вычисление правильного значения выполняется в первый раз, когда вы используете var для автодополнения. Это делается вызовом fun без аргументов. Значение, возвращаемое fun, становится постоянным значением var.

Вот пример:

(defvar foo (lazy-completion-table foo make-my-alist))

Существует несколько функций, которые принимают существующую таблицу дополнений и возвращают измененную версию. completion-table-case-fold возвращает таблицу с игнорированием регистра. completion-table-in-turn и completion-table-merge объединяют несколько входных таблиц разными способами. completion-table-subvert изменяет таблицу, используя другой начальный префикс. completion-table-with-quoting возвращает таблицу, подходящую для работы с цитируемым текстом. completion-table-with-predicate фильтрует таблицу с помощью функции предиката. completion-table-with-terminator добавляет завершающую строку.