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

13

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

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

AVV
источник
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
источник
Не хочешь объяснить, почему голосование "за"?
Пользователь 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
Томас Дехез
источник