Jak mogę ocenić elisp w pliku orgmode, gdy jest otwarty?

13

Mam kod elisp, który chciałbym uruchamiać w plikach orgmode podczas ładowania (różne dla różnych plików i zdefiniowane w samym pliku). Czy jest na to sposób? Nic nie widziałem w http://orgmode.org/manual/In_002dbuffer-settings.html

Jeśli mogę dodać coś do inicjowania emacsa, który uruchamia specjalnie nazwany blok kodu za każdym razem, gdy ładuje się plik orgmode, może to być rozwiązanie, ale nie jestem pewien, jak to zrobić, a idealnie jest coś wbudowanego.

avv
źródło
1
Może zmienne lokalne dla plików?
Dan
To działa! Czy chcesz uzyskać odpowiedź, którą mogę zaakceptować?
avv
Po dalszej myśli, że jest to bardzo brudne środowisko do edycji, więc dobrym rozwiązaniem byłoby, gdyby lokalna zmienna pliku uruchomiła nazwany blok kodu.
avv
Owinąć to może prognozą czy lambda?
Dan
3
Możesz także użyć, # -*- eval: (lisp code here) -*-ale musisz także zdawać sobie sprawę z niebezpieczeństw. Nawet jeśli nie udostępnisz tych dokumentów innym osobom, interpretacja Emacs Lisp będzie oznaczać, że zmiana może przypadkowo spowodować utratę danych. Ponadto tryb hook wydaje się lepszą opcją, jeśli chcesz uruchomić ten sam kod dla więcej niż jednego pliku.
wvxvw

Odpowiedzi:

9

To rozwiązanie nie wymaga zmiany init.el(z niewielkimi modyfikacjami). Wiąże się to jednak z ocenami lokalnymi dla plików - ale dokładnie o to poprosił PO. Zalety rozwiązania to:

  • prosi o potwierdzenie oceny kodu
  • Kod elisp może być edytowany i testowany w środowisku org-babel
  • ponieważ rozwiązanie nie wymaga modyfikacji init.elpliku orgmode, mogą być udostępniane (zaufanym) użytkownikom

Przeredagowuję tutaj rozwiązanie.

Dodaj blok src gdzieś w swoim pliku:

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

Następnie umieść to na końcu pliku orgmode:

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

Dodałem, (outline-hide-sublevels 1)ponieważ lubię ukrywać blok src w nagłówku i chcę, aby podpoziomy były ukryte podczas uruchamiania. Bez tego oświadczenia podpoziomy zostaną rozszerzone o (org-babel-goto-named-src-block "startup").

Dzięki temu rozwiązaniu emacs poprosi 2 razy o pozwolenie na wykonanie (1: zastosuj zmienne lokalne; 2: uruchom blok „startup” -src-block). Ponieważ w moim pliku jest wiele bloków src, ustawiłem inną zmienną lokalną dla pliku org-confirm-babel-evaluate, taką jak ta:

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

Ostrzeżenie: Po dodaniu tego emacs poprosi tylko raz o zgodę na wykonanie - wszystkie bloki src w tym pliku mogą być teraz wykonywane bez dalszego potwierdzenia. Jak zauważyli wcześniej inni, takie zachowanie może być niebezpieczne i powinieneś być bardzo ostrożny z tym ustawieniem.

Jednak twierdzę, że to rozwiązanie (szczególnie pierwsza wersja) jest bezpieczniejsze niż to, które podał Joe Corneli, ponieważ przynajmniej zostaniesz poproszony o potwierdzenie wykonania. Rozwiązanie Joe oceni specjalny blok bez potwierdzenia, jeśli zostanie znaleziony w pliku. Osoba atakująca musiałaby odgadnąć nazwę specjalnego bloku, oczywiście ...

Używam tego podejścia do pisania dużych dokumentów, które wymagają np. Dostosowania mechanizmów eksportu organizacji.

ben
źródło
5

org-mode... Oprócz haków outline-modemógł działać tryb macierzysty , ten tryb uruchamia hak org-mode-hook, co jest ostatnim krokiem podczas inicjalizacji.

Więc w twoim 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
źródło
Dla mnie to brzmi bardziej rozsądnie niż zmienne lokalne dla plików. Ale może coś mi umknęło.
Drew
@Joe Corneli A co byś włożył do rzeczywistego pliku org?
incandescentman
Nic specjalnego oprócz „specjalnego bloku”.
Joe Corneli
3

Ponieważ prosisz

(różne dla różnych plików i zdefiniowane w samym pliku)

następnie wypróbuj to rozwiązanie .

Użytkownik Emacsa
źródło
Chcesz wyjaśnić, dlaczego głosowanie w dół?
Użytkownik Emacsa,
To dlatego, że odradzane są odpowiedzi, które są tylko linkami do innych odpowiedzi. Biorąc to pod uwagę, może to pytanie jest duplikatem tego, z którym się łączysz?
Linus Arver
1

Zgadzam się z sugestią @Joe Corneli dotyczącą używania haka.

Przyszło mi też do głowy, że możesz wykorzystać tutaj zakładki: postaw konkretny skok na zakładce. Zaletą zakładki do bloku kodu jest to, że zazwyczaj jest on przenoszony automatycznie (np. Wraz ze zmianą zawartości pliku), więc zlokalizowanie bloku zwykle powinno odbywać się automatycznie.

[Ale nie jest dla mnie jasne, dlaczego masz kod w plikach w trybie Org, a nie gdzie indziej. Przyjmujemy to jako dane rozwiązanie problemu, ale zastanawiam się, dlaczego to robisz. Powiadomienie nas o projekcie w tym zakresie może pomóc w lepszej pomocy.]

Rysował
źródło
0

Próbowałem poprawić kod z Joe Corneli:

Potrzebujesz tego w pliku 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)

Za każdym razem, gdy otworzysz bufor w trybie organizacji, wyszuka blok źródłowy o nazwie startblock, a jeśli zostanie znaleziony, wykona go.

W swoich plikach w trybie org możesz następnie umieścić:

#+NAME: startblock
#+BEGIN_SRC emacs-lisp
  ;; Any code you want
#+END_SRC
Thomas Dehaeze
źródło