评估Emacs中的随机elisp函数

时间:2010-08-31 06:55:46

标签: emacs elisp

所以,我一直在玩this web site that creates random themes for Emacs。我一直在保存生成的.el文件并在启动Emacs时加载它们。可以通过评估前缀为inspiration-的elisp表达式来启动每个颜色主题。

不幸的是,我不知道elisp。有人可以帮我弄清楚如何编写一个函数来查看“灵感 - ”前缀函数是否可用,并随机评估其中一个函数?

3 个答案:

答案 0 :(得分:6)

我喜欢逐步建立这些问题的解决方案。如果您只是想尝试我的答案,请跳到最后的defun代码块。我转到*scratch*缓冲区,在lisp-interaction-mode中尝试这些代码段。您可以在表达式后键入C-j,Emacs将运行它并将结果插入缓冲区。

apropos函数搜索与某些模式匹配的符号,包括正则表达式。所以我们可以找到所有以“灵感 - ”开头的符号,如下所示:

(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))

现在让我们把它变成一个新的lisp函数(让我们的名字不能以inspiration-开头)。我会将其标记为interactive,以便除了在其他elisp代码中使用它之外,您还可以通过M-x use-random-inspiration运行它。另一个重大变化是使用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文件并尝试一下。

编辑:避免使用Apropos缓冲区

(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*")))

答案 1 :(得分:4)

当哈罗德击败我时,我正在努力解决这个问题。但是,他的回答让我思考。我以前不知道灵感主题生成器,我真的很喜欢这个想法!所以,虽然这不是你要求的,但读这个问题的人仍然会感兴趣。它从Inspiration站点中选择一个随机主题,将其下载到缓冲区,对其进行评估,并在删除缓冲区后执行生成的函数。

基本上,它是随机颜色主题。我还没有想出用于光明和黑暗的随机编号方案,但如果我这样做,这很容易变成random-darkrandom-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))))))

答案 2 :(得分:0)

这不是一个真正的答案,但在找到灵感主题生成器后,我真的想要一个很好的方法来调整它们......

所以我做了这个...... http://jasonm23.github.com/