Comment puis-je évaluer elisp dans un fichier orgmode lorsqu'il est ouvert?

13

J'ai du code elisp que j'aimerais exécuter dans des fichiers orgmode lors de leur chargement (différent pour différents fichiers et défini dans le fichier lui-même). Y a-t-il un moyen de faire cela? Je n'ai rien vu sur http://orgmode.org/manual/In_002dbuffer-settings.html

Si je peux ajouter quelque chose à l'initialisation emacs qui exécute un bloc de code spécialement nommé chaque fois qu'un fichier orgmode se charge, cela pourrait être une solution, mais je ne sais pas comment faire, et idéalement il y a quelque chose de intégré.

avv
la source
1
Variables locales de fichier, peut-être?
Dan
Ça marche! Voulez-vous en faire une réponse que je peux accepter?
avv
Après réflexion, c'est un environnement très compliqué à modifier, donc une bonne solution aurait la variable locale de fichier exécutant un bloc de code nommé.
avv
Enveloppez-le dans un progn ou un lambda, peut-être?
Dan
3
Vous pouvez également utiliser, # -*- eval: (lisp code here) -*-mais vous devez également être conscient des dangers. Même si vous ne partagez pas ces documents avec quelqu'un d'autre, la nature interprétée d'Emacs Lisp signifie qu'un changement peut entraîner accidentellement une perte de données. En outre, le hook de mode semble être une meilleure option si vous souhaitez exécuter le même code pour plusieurs fichiers.
wvxvw

Réponses:

9

Cette solution ne nécessite aucun changement init.el(avec des modifications mineures). Cela implique des évaluations locales des fichiers, mais c'est exactement ce que le PO a demandé. Les avantages de la solution sont:

  • demande une confirmation pour évaluer le code
  • Le code elisp peut être édité et testé dans l'environnement org-babel
  • car la solution ne nécessite pas de modifications init.eldu fichier orgmode peut être partagée entre les utilisateurs (de confiance)

Je reformule la solution ici.

Ajoutez un bloc src quelque part dans votre fichier:

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

Ensuite, mettez ceci à la fin de votre fichier orgmode:

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

J'ai ajouté (outline-hide-sublevels 1)parce que j'aime cacher le bloc src dans une rubrique et que les sous-niveaux soient cachés au démarrage. Sans cette déclaration, les sous-niveaux seront étendus de (org-babel-goto-named-src-block "startup").

Avec cette solution, emacs demandera 2 fois l'autorisation d'exécuter (1er: appliquer les variables locales; 2e: exécuter "startup" -src-block). Comme j'ai beaucoup de blocs src dans mon fichier, j'ai défini une autre variable de fichier local org-confirm-babel-evaluate, comme ceci:

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

Avertissement: Avec cet ajout, emacs ne demandera qu'une seule fois l'autorisation d'exécuter - tous les blocs src de ce fichier peuvent maintenant être exécutés sans autre confirmation. Comme d'autres l'ont déjà souligné, ce comportement peut être dangereux et vous devez être très prudent avec ce paramètre.

Cependant, je dirais que cette solution (en particulier la première version) est plus sécurisée que celle donnée par Joe Corneli car au moins il vous sera demandé de confirmer l'exécution. La solution de Joe évaluera le bloc spécial sans confirmation, s'il se trouve dans le fichier. Un attaquant devrait deviner le nom du bloc spécial, bien sûr ...

J'utilise cette approche pour écrire des documents volumineux qui nécessitent, par exemple, des adaptations aux mécanismes d'export org.

ben
la source
5

org-mode... En plus de tous les hooks que son mode parent a outline-modepu exécuter, ce mode exécute le hook org-mode-hook, comme dernière étape lors de l'initialisation.

Donc, dans votre 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
la source
Cela me semble plus raisonnable que les fichiers VAR locaux pour cette tâche. Mais peut-être que je manque quelque chose.
Drew
@Joe Corneli Et ensuite que mettriez-vous dans le fichier org réel?
incandescentman
Rien de spécial à part le "bloc spécial".
Joe Corneli
3

Puisque vous demandez

(différent pour différents fichiers et défini dans le fichier lui-même)

essayez ensuite cette solution .

Utilisateur Emacs
la source
Voulez-vous expliquer pourquoi le vote négatif?
Emacs User
C'est parce que les réponses qui ne sont que des liens vers d'autres réponses sont déconseillées. Cela étant dit, cette question est peut-être une dupe de celle à laquelle vous êtes liée?
Linus Arver
1

Je suis d'accord avec la suggestion de @Joe Corneli concernant l'utilisation d'un crochet.

Il me vient aussi à l'esprit que vous pouvez tirer parti des signets ici: mettez un saut de signet spécifique sur le crochet. Un avantage d'un signet dans le bloc de code est qu'il est généralement déplacé automatiquement (par exemple lorsque le contenu du fichier change), donc la localisation du bloc doit généralement être effectuée automatiquement.

[Mais je ne comprends pas pourquoi vous avez le code dans les fichiers en mode Org, plutôt qu'ailleurs. Nous considérons cela comme une donnée, selon l'énoncé du problème, mais je me demande pourquoi vous faites cela. Nous faire savoir plus sur la conception à cet égard pourrait conduire à une meilleure aide.]

A dessiné
la source
0

J'ai essayé d'améliorer le code de Joe Corneli:

Vous en avez besoin dans votre fichier 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)

Chaque fois que vous ouvrez un tampon en mode org, il recherchera un bloc source nommé startblock, s'il en trouve un, il l'exécutera.

Dans vos fichiers en mode org, vous pouvez ensuite mettre:

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