Мне нравится наращивать решение этих проблем постепенно. Если вы просто хотите попробовать мой ответ, перейдите к блоку кода defun
в конце. Я перехожу в буфер *scratch*
, в lisp-interaction-mode
, чтобы попробовать эти фрагменты кода. Вы можете ввести C-j
после выражения и Emacs запустит его и введет результаты в буфер.
Функция apropos
выполняет поиск символов, соответствующих некоторому шаблону, включая регулярные выражения. Таким образом, мы можем найти все символы, начиная с «inspiration-» как так:
(apropos "^inspiration-\*" t)
Но этот результат имеет список для каждого символа с какой-либо другой информацией. Мы можем отказаться от этого и просто взять имя символа, который приходит первым, используя first
функцию:
(mapcar #'first (apropos "^inspiration-\*" t))
Некоторые из тех, которые не являются функциями, поэтому давайте удалим любые, которые проваливают functionp
тест:
(let ((symbols (mapcar #'first (apropos "^inspiration-\*" t))))
(remove-if-not #'functionp symbols))
Теперь давайте случайным образом выберите один из них. Я переключаюсь с let
на let*
, потому что let*
позволяет мне ссылаться на более ранние определения в той же инициализации, например. используя symbols
при определении functions
.
(let* ((symbols (mapcar #'first (apropos "^inspiration-\*" t)))
(functions (remove-if-not #'functionp symbols))
(number (random (length functions))))
(nth number functions))
Теперь давайте обратимся, что в новой функции Лиспа (и давайте не будем иметь начало имен с inspiration-
). Я буду отмечать его как interactive
, чтобы вы могли запустить его через M-x use-random-inspiration
в дополнение к его использованию в другом коде elisp. Другие большие изменения заключаются в использовании funcall
на самом деле запустить случайно выбранную функцию:
(defun use-random-inspiration()
(interactive)
(let* ((symbols (mapcar #'first (apropos "^inspiration-\*" t)))
(functions (remove-if-not #'functionp symbols))
(number (random (length functions))))
(funcall (nth number functions))))
Так добавить, что в файл $HOME/.emacs
и попробовать его.
EDIT: Избегайте буфера всплывающих КСТАТИ
(defun use-random-inspiration()
(interactive)
(let* ((pop-up-windows nil)
(symbols (mapcar #'first (apropos "^inspiration-\*" t)))
(functions (remove-if-not #'functionp symbols))
(number (random (length functions))))
(funcall (nth number functions)))
(kill-buffer (get-buffer "*Apropos*")))
Гарольд - спасибо. Это именно то, что мне нужно. Я нашел «mapatoms» и начал пытаться что-то построить с этим, но не зная elisp, это была медленная дорога для прокладывания. Это намного проще. – qrest
Оказывается, единственная проблема, с которой я сталкиваюсь, заключается в том, что функция apropos вызывает новое окно в буфере * Apropos *. Я не вижу способа подавить его, но не так ли? – qrest
Понадобилось время, чтобы выяснить, что всплывающее окно всплывает. Я добавил исправление, помеченное как EDIT. Оказывается, это исправление в 2 части. Во-первых, нам нужно установить переменную pop-up-windows равной нулю, чтобы экран не разбивался пополам. Это заставляет всплывающее окно захватывать окно. Затем мы можем сразу же удалить буфер * Apropos *, чтобы вернуться в буфер, в котором мы были. –