Spec-Zone.ru › Elisp

Поиск определений

Такие инструменты, как встроенная команда справки Emacs C-h f (см. Справка в Руководстве GNU Emacs), могут находить место определения функций и других объектов Lisp в исходном коде. Для этого они используют переменную find-function-regexp-alist.

Ассоциативный список find-function-regexp-alist связывает типы объектов с регулярным выражением или функцией, которая находит определение этого объекта в исходном файле. car каждого элемента — это символ, описывающий тип объекта, или nil, что означает функцию, определённую с помощью defun. cdr каждого элемента может быть одним из следующих значений:

  • Символ, значением которого является строка, интерпретируемая как регулярное выражение.
  • Символ, обозначающий функцию, которая может найти определение.
  • Конс-ячейка, где car — это регулярное выражение (или функция, возвращающая его), а cdr — это сопоставитель форм: функция, создающая сопоставитель для форм, раскрытых макросами.

Строка регулярного выражения фактически является строкой формата, и %s будет заменено именем искомого символа.

Функция будет вызвана с одним аргументом — (символом, обозначающим) искомый объект.

Функция-сопоставитель форм в значении конс-ячейки вызывается с одним аргументом (искомым символом) и должна возвращать функцию; эта функция должна принимать форму и возвращать значение, отличное от nil, если форма определяет искомый символ. Это полезно для поиска определений, созданных при раскрытии макросов.

Если искомая функция определена макросом, Emacs может быть трудно найти место её определения в исходном коде. Вызов макроса может иметь неожиданный вид, и find-function-regexp-alist не сможет обнаружить определение.

Например, define-derived-mode (см. Определение производных режимов) может неявно определять функцию или переменную, относящуюся к конкретному режиму; или ваша программа на Lisp может генерировать вызов defun во время выполнения для определения функции. В этих и подобных случаях свойство definition-name символа должно содержать другой символ, определение которого можно найти с помощью текстового поиска и код которого определяет исходный символ. В примере с define-derived-mode значением этого свойства у определяемых им функций и переменных должен быть символ режима.

В некоторых случаях определение невозможно найти, выполнив поиск определения другого символа. Например, тестовый файл может использовать макрос для генерации вызовов ert-deftest (см. Как писать тесты в ERT: регрессионное тестирование Emacs Lisp), где код представляет собой шаблонный текст, а передавать нужно только изменяющиеся данные. В таких случаях свойство find-function-type-alist символа может содержать ассоциативный список, дополняющий find-function-regexp-alist и указывающий, как находить определения символов этого типа.

Проще всего поддерживать свойство find-function-regexp-alist с помощью вспомогательной функции find-function-update-type-alist.

Функция: find-function-update-type-alist symbol type variable

Обновляет свойство find-function-type-alist у symbol, добавляя новый элемент с ключом type и значением variable.

В примере с макросом, определяющим вызовы ert-deftest, макрос может добавлять свойство find-function-type-alist каждому определённому тесту, связывая ert--test (внутренний тип тестов ERT) с именем регулярного выражения или функции, которая находит соответствующий вызов макроса. Файл, определяющий макрос, также должен содержать эту функцию или регулярное выражение для поиска определения. Вот пример поиска определения с помощью функции:

(defmacro define-foo-test (data)
  "Define a test of the foo system using DATA."
  (declare (debug (&rest sexp)))
  (let ((test-name (intern (concat ...))))
    `(progn
       (find-function-update-type-alist
        ',test-name 'ert--test 'foo-find-test-def-function)
       (ert-deftest ,test-name ()
         ,(concat "Test foo with " ...)
         ...))))
(defun foo-find-test-def-function (test-name)
  "Search for the `define-foo-test' call defining TEST-NAME.
Return non-nil if the definition is found."
  (let ((regexp ...))
    (re-search-forward regexp nil t)))

Copyright © 1990-1996, 1998-2026 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Finding-Definitions.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API