Как я могу оценить elisp в файле orgmode при его открытии?


13

У меня есть elisp-код, который я хотел бы запускать в файлах orgmode при их загрузке (различается для разных файлов и определяется в самом файле). Есть ли способ сделать это? Я ничего не видел в http://orgmode.org/manual/In_002dbuffer-settings.html

Если я могу добавить что-то в инициализацию emacs, которая запускает блок кода со специальным именем при загрузке файла orgmode, это может быть решением, но я не уверен, как это сделать, и в идеале что-то встроено.


1
Файловые переменные, возможно?
Дан

Это работает! Вы хотите сделать ответ, который я могу принять?
Авв

Если подумать, это очень грязная среда для редактирования, поэтому хорошим решением будет локальная переменная файла, выполняющая именованный блок кода.
Авв

Оберните это в прогу или лямбду, возможно?
Дан

3
Вы также можете использовать, # -*- eval: (lisp code here) -*-но вы также должны знать об опасностях. Даже если вы не передадите эти документы кому-либо еще, интерпретируемая природа Emacs Lisp будет означать, что изменение может случайно привести к потере данных. Кроме того, режим ловушки звучит как лучший вариант, если вы хотите запустить один и тот же код для более чем одного файла.
wvxvw

Ответы:


9

Это решение не требует изменений init.el(с незначительными изменениями). Это включает в себя локальные оценки файлов - но это именно то, о чем просил OP. Преимущества решения:

  • запрашивает подтверждение для оценки кода
  • код elisp можно редактировать и тестировать в среде org-babel
  • поскольку решение не требует изменений в init.elфайле orgmode, оно может быть передано (доверенным) пользователям

Я перефразирую решение здесь.

Добавьте 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 дважды запросит разрешение на выполнение (1-е: применить локальные переменные; 2-е: выполнить «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-блоки в этом файле теперь могут выполняться без дальнейшего подтверждения. Как уже отмечали другие, такое поведение может быть опасным, и вы должны быть очень осторожны с этим параметром.

Тем не менее, я бы утверждать , что это решение (особенно первая версия) является более безопасным , чем один данным Джо Corneli , потому что по крайней мере у вас будет предложены для подтверждения для выполнения. Решение Джо оценит специальный блок без подтверждения, если он найден в файле. Злоумышленник, конечно, должен угадать название специального блока ...

Я использую этот подход для написания больших документов, которые требуют, например, адаптации к механизмам экспорта в орг.


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)

Для меня это звучит более разумно, чем файловые локальные переменные, для этой задачи. Но, возможно, я что-то упустил.
Дрю

@Joe Corneli А что бы вы поместили в настоящий файл org?
Лампа накаливания

Ничего особенного, кроме «особого блока».
Джо Корнели

3

Так как вы просите

(отличается для разных файлов и определяется в самом файле)

затем попробуйте это решение .


Не хочешь объяснить, почему голосование "за"?
Пользователь Emacs

Это потому, что ответы, которые являются просто ссылками на другие ответы, не рекомендуется. При этом, может быть, этот вопрос является обманом того, с кем вы связаны?
Линус Арвер

1

Я согласен с предложением @Joe Corneli об использовании крючка.

Мне также кажется, что вы могли бы использовать закладки здесь: поставить конкретный прыжок закладки на крючок. Преимущество закладки для блока кода состоит в том, что она, как правило, перемещается автоматически (например, при изменении содержимого файла), поэтому о местонахождении блока обычно следует заботиться автоматически.

[Но мне не понятно, почему у вас есть код в файлах режима Org, а не где-то еще. Мы принимаем это как данность, согласно постановке задачи, но мне интересно, почему вы это делаете. Дайте нам знать больше о дизайне в этом отношении, может помочь лучше.]


0

Я пытался улучшить код от Джо Корнели:

Это необходимо в вашем файле 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)

Каждый раз, когда вы открываете буфер режима org, он будет искать исходный блок с именем startblock, если он найден, он будет выполнять его.

В файлы org-mode вы можете поместить:

#+NAME: startblock
#+BEGIN_SRC emacs-lisp
  ;; Any code you want
#+END_SRC
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.