【问题标题】:Evaluating a random elisp function in Emacs在 Emacs 中评估随机 elisp 函数
【发布时间】:2010-08-31 06:55:46
【问题描述】:

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

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

【问题讨论】:

    标签: emacs elisp


    【解决方案1】:

    我喜欢逐步建立解决这些问题的方法。如果您只是想尝试我的答案,请跳到末尾的 defun 代码块。我去*scratch* 缓冲区,在lisp-interaction-mode 中尝试这些代码sn-ps。你可以在表达式后面输入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))
    

    现在让我们把它变成一个新的 lisp 函数(让我们的名字不要以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 文件中并尝试一下。

    编辑:避免 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*")))
    

    【讨论】:

    • 哈罗德——谢谢。这正是我所需要的。我找到了“mapatoms”并开始尝试用它来构建一些东西,但不知道 elisp 这是一条缓慢的道路。这要简单得多。
    • 原来我唯一的问题是 apropos 函数在 Apropos 缓冲区中打开了一个自己的新窗口。我没有办法抑制它,但你能吗?
    • 我花了一段时间才弄清楚那个中肯的窗口弹出。我已经为标记为 EDIT 的内容添加了一个修复程序。原来这是一个两部分修复。首先,我们需要将 pop-up-windows 变量设置为 nil,这样屏幕就不会分成两半。这使得弹出窗口接管窗口。然后我们可以立即终止 Apropos 缓冲区以返回到我们所在的缓冲区。
    【解决方案2】:

    当哈罗德击败我时,我正在努力解决这个问题。但是,他的回答让我开始思考。我以前不知道灵感主题生成器,我真的很喜欢这个主意!因此,虽然这不是您所要求的,但对于阅读此问题的人们来说仍然可能很有趣。它从 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))))))
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-03-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多