Wie kann ich elisp in einer Orgmode-Datei beim Öffnen auswerten?

13

Ich habe Elisp-Code, den ich beim Laden in Orgmode-Dateien ausführen möchte (unterschiedlich für verschiedene Dateien und in der Datei selbst definiert). Gibt es eine Möglichkeit, dies zu tun? Ich habe nichts in http://orgmode.org/manual/In_002dbuffer-settings.html gesehen

Wenn ich der Emacs-Initialisierung etwas hinzufügen kann, das beim Laden einer Orgmode-Datei einen speziell benannten Codeblock ausführt, ist dies möglicherweise eine Lösung, aber ich bin mir nicht sicher, wie das geht, und im Idealfall ist etwas integriert.

avv
quelle
1
Vielleicht dateilokale Variablen?
Dan
Das funktioniert! Möchten Sie daraus eine Antwort machen, die ich akzeptieren kann?
Avv
Wenn man weiter darüber nachdenkt, dass dies eine sehr unübersichtliche Umgebung ist, in der man sie bearbeiten kann, würde eine gute Lösung darin bestehen, dass die lokale Dateivariable einen benannten Codeblock ausführt.
Avv
Vielleicht in eine Prognose oder ein Lambda einwickeln?
Dan
3
Sie können auch verwenden, # -*- eval: (lisp code here) -*-aber Sie müssen sich auch der Gefahren bewusst sein. Selbst wenn Sie diese Dokumente nicht an Dritte weitergeben, führt die Interpretation von Emacs Lisp dazu, dass eine Änderung versehentlich zu Datenverlust führen kann. Außerdem klingt der Modus-Hook nach einer besseren Option, wenn Sie denselben Code für mehr als eine Datei ausführen möchten.
wvxvw

Antworten:

9

Diese Lösung erfordert keine Änderung init.el(mit geringfügigen Änderungen). Es handelt sich zwar um dateilokale Auswertungen - aber genau darum hat das OP gebeten. Vorteile der Lösung sind:

  • bittet um Bestätigung zur Auswertung des Codes
  • Elisp-Code kann in der org-babel-Umgebung bearbeitet und getestet werden
  • init.elDa für die Lösung keine Änderungen an der Organisationsmodusdatei erforderlich sind, können diese von (vertrauenswürdigen) Benutzern gemeinsam genutzt werden

Ich formuliere die Lösung hier neu.

Fügen Sie irgendwo in Ihrer Datei einen src-Block hinzu:

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

Dann setzen Sie dies am Ende Ihrer orgmode-Datei:

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

Ich habe hinzugefügt, (outline-hide-sublevels 1)weil ich den src-Block gerne in einer Überschrift ausblenden möchte und möchte, dass die Unterebenen beim Start ausgeblendet werden. Ohne diese Aussage werden die Unterebenen um erweitert (org-babel-goto-named-src-block "startup").

Bei dieser Lösung werden emacs zweimal um die Erlaubnis zur Ausführung gebeten (1. lokale Variablen anwenden; 2. "Startup" -src-Block ausführen). Da ich viele src-Blöcke in meiner Datei habe, habe ich eine andere dateilokale Variable festgelegt org-confirm-babel-evaluate, wie folgt:

# 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:

Warnung: Mit diesem Zusatz fordert emacs nur einmal zur Ausführung auf - alle src-Blöcke in dieser Datei können jetzt ohne weitere Bestätigung ausgeführt werden. Wie andere bereits erwähnt haben, kann dieses Verhalten gefährlich sein, und Sie sollten mit dieser Einstellung sehr vorsichtig sein.

Ich würde jedoch argumentieren , dass diese Lösung (vor allem der erste Version) ist sicherer als die von Joe Corneli gegeben , weil zumindest Sie werden zur Bestätigung aufgefordert werden , auszuführen. Joes Lösung wertet den speziellen Block ohne Bestätigung aus, wenn er in der Datei gefunden wird. Ein Angreifer müsste natürlich den Namen des Spezialblocks erraten ...

Ich verwende diesen Ansatz, um große Dokumente zu schreiben, die beispielsweise Anpassungen an den Organ-Export-Mechanismen erfordern.

ben
quelle
5

org-mode... Zusätzlich zu allen Hooks, die outline-modemöglicherweise im übergeordneten Modus ausgeführt wurden, wird in diesem Modus der Hook org-mode-hookals letzter Schritt während der Initialisierung ausgeführt.

Also, in Ihrem 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
quelle
Das klingt für mich für diese Aufgabe vernünftiger als dateilokale Variablen. Aber vielleicht fehlt mir etwas.
Drew
@ Joe Corneli Und was würden Sie dann in die eigentliche Organisationsdatei einfügen?
Glühlampen
Nichts Besonderes außer dem "Spezialblock".
Joe Corneli
3

Da fragst du nach

(unterschiedlich für verschiedene Dateien und in der Datei selbst definiert)

Versuchen Sie dann diese Lösung .

Emacs Benutzer
quelle
Möchtest du erklären, warum die Abstimmung nicht stimmt?
Emacs User
Dies liegt daran, dass Antworten, die nur Links zu anderen Antworten sind, nicht empfohlen werden. Davon abgesehen, ist diese Frage vielleicht ein Betrug der Frage, mit der Sie verbunden sind?
Linus Arver
1

Ich stimme dem Vorschlag von @Joe Corneli zu, einen Haken zu verwenden.

Mir fällt auch ein, dass Sie hier Lesezeichen nutzen können: Setzen Sie einen bestimmten Lesezeichensprung auf den Haken. Ein Vorteil eines Lesezeichens für den Codeblock besteht darin, dass er normalerweise automatisch verschoben wird (z. B. wenn sich der Dateiinhalt ändert). Daher sollte das Auffinden des Blocks normalerweise automatisch erledigt werden.

[Aber mir ist nicht klar, warum Sie den Code in den Org-Modus-Dateien haben, anstatt anderswo. Wir nehmen das gemäß der Problemstellung als gegeben an, aber ich frage mich, warum Sie das tun. Wenn Sie uns diesbezüglich mehr über das Design erfahren, kann dies zu einer besseren Hilfe führen.]

Drew
quelle
0

Ich habe versucht, den Code von Joe Corneli zu verbessern:

Sie benötigen das in Ihrer init.el-Datei:

  (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)

Jedes Mal, wenn Sie einen Puffer im Organisationsmodus öffnen, wird nach einem Quellblock mit dem Namen startblock gesucht. Wenn einer gefunden wird, wird er ausgeführt.

In Ihre Dateien im Organisationsmodus können Sie dann Folgendes einfügen:

#+NAME: startblock
#+BEGIN_SRC emacs-lisp
  ;; Any code you want
#+END_SRC
Thomas Dehaeze
quelle