评估Emacs中的随机elisp函数

qre*_*est 3 emacs elisp

所以,我一直在玩这个为Emacs创建随机主题的网站.我一直在保存生成的.el文件并在启动Emacs时加载它们.可以通过评估带有前缀的elisp表达式来启动每个颜色主题inspiration-.

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

Har*_*d L 6

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

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

(apropos "^inspiration-\*" t)
Run Code Online (Sandbox Code Playgroud)

但是该结果具有每个符号的列表以及一些其他信息.我们可以丢弃它,只需使用以下first函数获取符号名称:

(mapcar #'first (apropos "^inspiration-\*" t))
Run Code Online (Sandbox Code Playgroud)

其中一些不是函数,所以让我们删除任何未通过functionp测试的函数:

(let ((symbols (mapcar #'first (apropos "^inspiration-\*" t))))
  (remove-if-not #'functionp symbols))
Run Code Online (Sandbox Code Playgroud)

现在让我们随机选择其中一个.我正在切换letlet*因为let*允许我在同一初始化中引用先前的定义,例如symbols在定义时使用functions.

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

现在让我们把它变成一个新的lisp函数(让我们没有名字开头inspiration-).我会将其标记为除了在其他elisp代码中使用它之外interactive,您还可以运行它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))))
Run Code Online (Sandbox Code Playgroud)

所以将它添加到您的$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*")))
Run Code Online (Sandbox Code Playgroud)