打开orgmode文件时,如何评估elisp?


13

我有elisp代码,它们希望在加载时在orgmode文件中运行(不同的文件不同,并且在文件本身中定义)。有没有办法做到这一点?我没有在http://orgmode.org/manual/In_002dbuffer-settings.html中看到任何内容

如果我可以在emacs初始化中添加一些在加载orgmode文件时运行专门命名的代码块的东西,那可能是一个解决方案,但是我不确定如何做到这一点,并且理想情况下内置了一些东西。


1
也许是文件局部变量?

那个有效!您是否想让它成为我可以接受的答案?
2015年

进一步考虑,这是一个非常混乱的编辑环境,因此一个好的解决方案是使文件局部变量运行一个命名代码块。
2015年

可以将其包裹在progn或lambda中吗?

3
您也可以使用,# -*- eval: (lisp code here) -*-但也必须意识到这些危险。即使您不与其他任何人共享这些文档,Emacs Lisp的解释性也将意味着更改可能会意外导致数据丢失。另外,如果您想为多个文件运行相同的代码,则模式挂钩听起来是一个更好的选择。
wvxvw 2015年

Answers:


9

解决方案无需进行任何更改init.el(只需进行少量修改)。尽管它涉及文件本地评估-但这正是OP所要求的。该解决方案的优点是:

  • 要求确认以评估代码
  • elisp代码可以在org-babel环境中进行编辑和测试
  • 由于该解决方案不需要修改init.elorgmode文件,因此可以在(可信)用户之间共享

我在这里改写解决方案。

在文件中的某处添加一个src块:

#+NAME: startup
#+BEGIN_SRC emacs-lisp
(your-code-here)
#+END_SRC

然后,将其放在orgmode文件的末尾:

# Local Variables:
# eval: (progn (org-babel-goto-named-src-block "startup") (org-babel-execute-src-block) (outline-hide-sublevels 1))
# End:

添加(outline-hide-sublevels 1)是因为我想将src块隐藏在标题中,并希望在启动时隐藏子级别。没有此声明,子级别将由扩展(org-babel-goto-named-src-block "startup")

使用此解决方案,emacs将询问两次执行许可(第一个:应用本地变量;第二个:执行“ startup” -src-block)。由于我的文件中包含许多src块,因此我设置了另一个file-local-variable org-confirm-babel-evaluate,如下所示:

# Local Variables:
# org-confirm-babel-evaluate: nil
# eval: (progn (org-babel-goto-named-src-block "startup") (org-babel-execute-src-block) (outline-hide-sublevels 1))
# End:

警告:添加此命令后,emacs将仅提示一次执行权限- 该文件中的所有src块现在都可以执行而无需进一步确认。正如其他人之前指出的那样,此行为可能很危险,因此使用此设置时应格外小心。

但是,我认为这种解决方案(尤其是第一个版本)比Joe Corneli提供的解决方案更安全因为至少要求您确认执行。如果在文件中找到特殊块,Joe的解决方案将评估该特殊块,而无需确认。当然,攻击者必须猜测特殊块的名称...

我正在使用这种方法来编写大型文档,这些文档需要例如适应org-export机制。


5

org-mode...除了outline-mode可能已运行其挂钩模式的任何挂钩之外,此模式还将运行挂钩org-mode-hook,这是初始化期间的最后一步。

因此,在您的init.el中:

(defun function-that-finds-and-evaluates-special-block ()
;; DWIM :-)
)
(add-hook 'org-mode-hook 'function-that-finds-and-evaluates-special-block)

对于我来说,这听起来比文件本地var更合理。但是也许我想念一些东西。
Drew

@Joe Corneli然后您将在实际的org文件中放入什么?
白炽灯

除了“特殊块”外,没有什么特别的。
Joe Corneli

3

既然你要

(针对不同的文件,并在文件本身中定义)

然后,尝试此解决方案


关心解释为什么要投反对票?
Emacs用户

这是因为不鼓励只是与其他答案的链接的答案。话虽这么说,也许这个问题是您所链接的问题的重复?
Linus Arver

1

我同意@Joe Corneli关于使用钩子的建议。

我也想到您可以在这里利用书签:将特定的书签跳转到钩子上。将书签添加到代码块的一个优点是,它通常会自动重定位(例如,随着文件内容的更改),因此通常应自动注意定位代码块的位置。

[但是我不清楚您为什么将代码保存在组织模式文件中,而不是在其他地方。根据问题陈述,我们将其作为给定值,但是我想知道为什么您要这样做。让我们对这方面的设计有更多的了解可能会带来更好的帮助。]


0

我试图改善Joe Corneli的代码:

您需要在init.el文件中:

  (defun tdh/eval-startblock ()
    (if (member "startblock" (org-babel-src-block-names))
      (save-excursion
        (org-babel-goto-named-src-block "startblock")
        (org-babel-execute-src-block))
      nil
      )
    )
  (add-hook 'org-mode-hook 'tdh/eval-startblock)

每次打开组织模式缓冲区时,它将搜索名为startblock的源代码块,如果找到该源代码块,它将执行它。

然后,您可以在组织模式文件中输入:

#+NAME: startblock
#+BEGIN_SRC emacs-lisp
  ;; Any code you want
#+END_SRC
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.