2010-08-31 4 views
3

Итак, я получал удовольствие от this web site that creates random themes for Emacs. Я сохраняю результирующие файлы .el и загружаю их при запуске Emacs. Каждая цветовая тема может быть начата путем оценки выражения elisp с префиксом inspiration-.Оценка случайной функции elisp в Emacs

К сожалению, я не знаю elisp. Может ли кто-нибудь помочь мне выяснить, как я могу написать функцию, которая смотрит на то, какие функции «вдохновения» префиксов доступны и случайно оценивают один из них?

ответ

6

Мне нравится наращивать решение этих проблем постепенно. Если вы просто хотите попробовать мой ответ, перейдите к блоку кода 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*"))) 
+0

Гарольд - спасибо. Это именно то, что мне нужно. Я нашел «mapatoms» и начал пытаться что-то построить с этим, но не зная elisp, это была медленная дорога для прокладывания. Это намного проще. – qrest

+0

Оказывается, единственная проблема, с которой я сталкиваюсь, заключается в том, что функция apropos вызывает новое окно в буфере * Apropos *. Я не вижу способа подавить его, но не так ли? – qrest

+0

Понадобилось время, чтобы выяснить, что всплывающее окно всплывает. Я добавил исправление, помеченное как EDIT. Оказывается, это исправление в 2 части. Во-первых, нам нужно установить переменную pop-up-windows равной нулю, чтобы экран не разбивался пополам. Это заставляет всплывающее окно захватывать окно. Затем мы можем сразу же удалить буфер * Apropos *, чтобы вернуться в буфер, в котором мы были. –

4

Я работал над ответом на это, когда Гарольд бил меня к удару. Но его ответ заставил меня задуматься. Я раньше не знал о генераторе темы «Вдохновение», и мне очень нравится идея! Итак, хотя это не то, о чем вы просили, все равно может быть интересно, если люди прочитают этот вопрос. Он выбирает случайную тему на сайте Inspiration, загружает ее в буфер, оценивает ее и выполняет результирующую функцию после удаления буфера.

В принципе, это случайные цветовые темы на кране. Я еще не понял случайную схему нумерации для светлых и темных, но если да, то это можно легко превратить в пару функций random-dark и random-light.Что вы могли бы тогда триггер на основе загруженного восхода и заход солнца для вашей широты и долготы ... =)

(defun random-inspiration() 
    "Downloads a random Inspiration theme and evaluates it." 
    (interactive) 
    (let* ((num (number-to-string (random 1000000))) 
     (buffer (url-retrieve-synchronously 
        (concat "http://inspiration.sweyla.com/code/emacs/inspiration" 
          num 
          ".el")))) 
    (save-excursion 
     (set-buffer buffer) 
     (goto-char (point-min)) 
     (re-search-forward "^$" nil 'move) 
     (eval-region (point) (point-max)) 
     (kill-buffer (current-buffer)) 
     (funcall (intern-soft (concat "inspiration-" num)))))) 
0

Это не совсем ответ, но после того, как найти генератор вдохновения темы, я действительно хотел хороший способ настроить их ...

Так что я сделал это ... http://jasonm23.github.com/