Bagaimana saya bisa mengevaluasi elisp dalam file orgmode ketika dibuka?

13

Saya memiliki kode elisp yang ingin saya jalankan dalam file orgmode ketika mereka memuat (berbeda untuk file yang berbeda, dan didefinisikan dalam file itu sendiri). Apakah ada cara untuk melakukan ini? Saya tidak melihat apa pun di http://orgmode.org/manual/In_002dbuffer-settings.html

Jika saya dapat menambahkan sesuatu ke inisialisasi emacs yang menjalankan blok kode bernama khusus setiap kali sebuah file orgmode memuat, itu mungkin merupakan solusi, tetapi saya tidak yakin bagaimana melakukannya, dan idealnya ada sesuatu yang tertanam di dalamnya.

avv
sumber
1
File-variabel lokal, mungkin?
Dan
Itu bekerja! Apakah Anda ingin membuatnya menjadi jawaban yang dapat saya terima?
avv
Dipikirkan lebih lanjut bahwa itu adalah lingkungan yang sangat berantakan untuk diedit, jadi solusi yang baik akan memiliki variabel file lokal menjalankan blok kode bernama.
avv
Bungkus dengan progn atau lambda, mungkin?
Dan
3
Anda juga bisa menggunakan # -*- eval: (lisp code here) -*-tetapi Anda juga harus mewaspadai bahayanya. Bahkan jika Anda tidak membagikan dokumen-dokumen ini dengan orang lain, sifat yang ditafsirkan dari Emacs Lisp akan berarti bahwa suatu perubahan secara tidak sengaja dapat mengakibatkan hilangnya data. Juga, mode hook terdengar seperti opsi yang lebih baik jika Anda ingin menjalankan kode yang sama untuk lebih dari satu file.
wvxvw

Jawaban:

9

Solusi ini tidak memerlukan perubahan init.el(dengan modifikasi kecil). Ini melibatkan evaluasi file-lokal, tetapi - itulah yang diminta OP. Keuntungan dari solusi ini adalah:

  • meminta konfirmasi untuk mengevaluasi kode
  • kode elisp dapat diedit dan diuji dalam lingkungan org-babel
  • karena solusinya tidak memerlukan modifikasi init.elpada file orgmode dapat dibagikan di antara pengguna (tepercaya)

Saya ulangi solusinya di sini.

Tambahkan src-block di suatu tempat di file Anda:

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

Kemudian, letakkan ini di akhir file-orgmode Anda:

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

Saya telah menambahkan (outline-hide-sublevels 1)karena saya suka menyembunyikan src-block di dalam heading dan ingin agar sublevel disembunyikan saat startup. Tanpa pernyataan ini, sublevel akan diperluas oleh (org-babel-goto-named-src-block "startup").

Dengan solusi ini, emacs akan meminta izin untuk mengeksekusi 2 kali (pertama: terapkan Variabel Lokal; 2: jalankan "startup" -src-block). Karena saya memiliki banyak blok-src di file saya, saya telah menetapkan variabel-file-lokal lain org-confirm-babel-evaluate,, seperti ini:

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

Peringatan: Dengan tambahan ini, emacs hanya akan meminta izin sekali untuk mengeksekusi - semua src-blok dalam file itu sekarang dapat dieksekusi tanpa konfirmasi lebih lanjut. Seperti yang telah ditunjukkan orang lain sebelumnya, perilaku ini bisa berbahaya dan Anda harus sangat berhati-hati dengan pengaturan ini.

Namun, saya berpendapat bahwa solusi ini (terutama versi pertama) lebih aman daripada yang diberikan oleh Joe Corneli karena setidaknya Anda akan diminta untuk melakukan konfirmasi. Solusi Joe akan mengevaluasi blok khusus tanpa konfirmasi, jika ditemukan dalam file. Seorang penyerang harus menebak nama blok khusus, tentu saja ...

Saya menggunakan pendekatan ini untuk menulis dokumen besar yang memerlukan, misalnya, adaptasi terhadap mekanisme ekspor-org.

ben
sumber
5

org-mode... Selain kait apa pun yang outline-modemungkin dijalankan oleh mode induknya , mode ini menjalankan hook org-mode-hook, sebagai langkah terakhir selama inisialisasi.

Jadi, di init.el Anda:

(defun function-that-finds-and-evaluates-special-block ()
;; DWIM :-)
)
(add-hook 'org-mode-hook 'function-that-finds-and-evaluates-special-block)
Joe Corneli
sumber
Bagi saya ini kedengarannya lebih masuk akal daripada var file-lokal, untuk tugas ini. Tapi mungkin aku kehilangan sesuatu.
Drew
@ Jooe Corneli Lalu apa yang akan Anda masukkan ke file org yang sebenarnya?
incandescentman
Tidak ada yang istimewa kecuali untuk "blok spesial".
Joe Corneli
3

Karena Anda memintanya

(berbeda untuk file yang berbeda, dan didefinisikan dalam file itu sendiri)

lalu, coba solusi ini .

Pengguna Emacs
sumber
Mau jelaskan mengapa suara turun?
Pengguna Emacs
Itu karena jawaban yang hanya tautan ke jawaban lain tidak disarankan. Yang sedang berkata, mungkin pertanyaan ini adalah penipuan dari yang Anda tautkan?
Linus Arver
1

Saya setuju dengan saran @ Jooe Corneli tentang menggunakan kail.

Terlintas dalam benak saya juga bahwa Anda dapat memanfaatkan bookmark di sini: letakkan penanda bookmark tertentu di hook. Keuntungan dari penunjuk ke blok kode adalah bahwa ia biasanya dipindahkan secara otomatis (mis. Ketika konten file berubah), sehingga menemukan blok tersebut biasanya secara otomatis dijaga.

[Tetapi tidak jelas bagi saya mengapa Anda memiliki kode dalam file mode-Org, bukan di tempat lain. Kami menganggap itu sebagai yang diberikan, per pernyataan masalah, tapi saya ingin tahu mengapa Anda melakukan itu. Memberi tahu kami lebih banyak tentang desain dalam hal itu bisa mengarah pada bantuan yang lebih baik.]

Drew
sumber
0

Saya telah mencoba meningkatkan kode dari Joe Corneli:

Anda memerlukannya di file init.el Anda:

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

Setiap kali Anda membuka buffer mode-org, itu akan mencari blok sumber bernama startblock, jika ada, itu akan menjalankannya.

Dalam file mode org Anda, Anda kemudian dapat menempatkan:

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