2010-08-31 77 views
3

因此,我一直在this web site that creates random themes for Emacs上玩。我一直保存结果.el文件并在启动Emacs时加载它们。通过评估以inspiration-为前缀的elisp表达式,可以开始每个颜色主题。评估Emacs中的随机elisp函数

不幸的是,我不知道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*允许我在相同的初始化中引用较早的定义,例如,定义functions时使用symbols

(let* ((symbols (mapcar #'first (apropos "^inspiration-\*" t))) 
     (functions (remove-if-not #'functionp symbols)) 
     (number (random (length functions)))) 
    (nth number functions)) 

现在,让我们把它转换成一个新的口齿不清功能(让我们不要有名字开始与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文件,并尝试一下。

编辑:当哈罗德打我冲避免中肯缓冲弹出

(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 2010-08-31 07:55:10

+0

原来我遇到的唯一问题是apropos函数会在* Apropos *缓冲区中创建一个自己的新窗口。我没有办法压制它,但你能吗? – qrest 2010-08-31 16:09:42

+0

花了我一会儿才弄清楚apropos窗口弹出。我已经添加了一个标记为EDIT的修复程序。原来它是一个2部分的修复。首先,我们需要将弹出窗口变量设置为零,以便屏幕不会分裂成一半。这使得弹出窗口占据了窗口。然后我们可以立即杀死* Apropos *缓冲区,回到我们所在的缓冲区。 – 2010-09-03 05:39:39

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

这是不是一个真正的答案,但找到的灵感主题发生器之后,我真想一个不错的方式来调整它们...

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