Bagaimana cara memaksa sesi org-babel untuk mengatur ulang atau menginisialisasi?

8

Jika saya menjalankan blok babel shell berikut

#+BEGIN_SRC sh :session one :results output
  ssh staging
#+END_SRC

#+BEGIN_SRC sh :session one :results output
  hostname
#+END_SRC

Org membuat buffer shell yang disebut one, dijalankan ssh stagingdan kemudian setelah terhubung, dijalankan hostnamepada staging. Namun, jika saya mengubah perintah ssh dan menjalankannya lagi, ia mencoba menjalankannya dari dalam sesi satu, dari host pentas. Jika saya menutup buffer oneitu me-reset sesi sebagai kali berikutnya perintah dijalankan dengan nama sesi itu akan membuatnya kembali. Apa yang saya belum dapat temukan adalah metode untuk memaksa blok babel tertentu untuk selalu menginisialisasi sesi baru.

Saya sadar bahwa untuk beberapa bahasa (khususnya khususnya elisp) ini tidak mungkin. Saya kira saya bisa menambahkan sesi dengan berisi blok elisp (kill-buffer "one"), tetapi lebih baik jika ini adalah argumen header jika memungkinkan. Saya juga menyadari bahwa untuk contoh ini saya hanya bisa menggabungkan keduanya menjadi satu blok tanpa sesi, tapi saya tertarik pada urutan yang lebih rumit.

Apakah ada :prologueperintah atau argumen khusus lainnya :sessionyang memaksa yang memblokir untuk menginisialisasi shell baru pada setiap doa?

dgtized
sumber
Tidak ada opsi seperti itu (atau parameter blok kode sumber) di Org 8.2.10, tetapi seharusnya cukup mudah untuk ditambahkan. Saya akan mulai dengan meretas org-babel-initiate-session.
Constantine

Jawaban:

5

Coba ini

Memaksa sesi org-babel untuk mengatur ulang atau menginisialisasi dengan menggunakan pernyataan kondisional elisp untuk secara dinamis mengatur nilai : header sesi pada blok kode pertama.

misalnya :session (if (get-buffer "one") (if (kill-buffer "one") (print "one") (print "one")) (print "one"))

Dalam kode di atas, fungsi get-buffer memeriksa apakah buffer bernama satu ada. Jika benar, membunuh-buffer fungsi membunuh yang satu penyangga kemudian mengembalikan nilai tatau nilyang diteruskan ke ifpernyataan. Dalam contoh khusus ini, ifpernyataan bersarang akan selalu mengembalikan nilai satu . Harap dicatat, saya masih belajar elisp.

Di bawah ini adalah contoh kode yang diperbarui:

#+BEGIN_SRC sh :session (if (get-buffer "one") (if (kill-buffer "one") (print "one") (print "one")) (print "one")) :results output
  ssh staging
#+END_SRC

#+BEGIN_SRC sh :session one :results output
  hostname
#+END_SRC

Setiap kali blok kode pertama dieksekusi, emacs akan meminta untuk membunuh satu buffer , sehingga Anda dapat mengatur ulang sesi saat Anda inginkan.

EDIT

Ups melewatkan bagian yang Anda selalu ingin agar buffer terbunuh, yaitu tidak ada bisikan . Jalankan blok ini terlebih dahulu untuk mematikan sementara meminta untuk membunuh buffer.

#+BEGIN_SRC elisp
  (setq kill-buffer-query-functions
    (remq 'process-kill-buffer-query-function
           kill-buffer-query-functions))
#+END_SRC

Harapan itu membantu!

Catatan: Kode ini diuji menggunakan versi emacs dan mode-org berikut.

GNU Emacs 24.4.1 (x86_64-apple-darwin14.0.0, NS apple-appkit-1343.14)
Org-mode version 8.2.10 (8.2.10-29-g89a0ac-elpa)

Sebagai kesimpulan, saya menemukan inspirasi teknis untuk jawaban ini di situs web org-memo dan kode contoh kill-buffer di stackoverflow.

Melioratus
sumber
@dgtized apakah jawaban ini membantu?
Melioratus
2
Saya tidak sadar Anda bisa menyematkan panggilan sesi, jadi terima kasih untuk itu. Yang mengatakan, seperti yang saya sebutkan dalam pertanyaan awal, saya sadar bahwa saya bisa mengotomatiskan kill-bufferuntuk memaksa sesi baru, tetapi lebih tertarik untuk belajar jika ada argumen blok dibangun ke mode-org, atau konvensi mapan lainnya untuk melakukan ini yang tidak saya sadari. Pendekatan Anda adalah solusi yang bagus, tetapi saya berharap ada pendekatan kanonik untuk ini.
dgtized
@dgtized - Apakah Anda mencari jawaban seperti ini? :session one :session-reset yes?
Melioratus
Sesuatu seperti itu tentu saja. Sekali lagi, ini adalah pertanyaan tentang praktik apa yang direkomendasikan untuk contoh ini. Tentunya orang lain memiliki sesi yang perlu diatur ulang, dan jika mereka hanya membunuh buffer itu baik-baik saja, tetapi saya ingin tahu apa praktik standarnya.
dgtized
@dgtized - Terima kasih telah menjelaskan! Ini pertanyaan yang bagus! Saya belum menemukan praktik standar yang terdokumentasi tetapi saya akan terus mencari .
Melioratus
2

Terinspirasi oleh @Melioratus.

Saat ini, org-babel menyediakan hook yang disebut org-babel-after-execute-hook. Saya memperluas argumen yang didukung dari blok org-babel src dengan menggunakannya:

(Saya menggunakan org-babel untuk elixir. Jika Anda ingin dukungan bahasa lain, perluas condsendiri.)

(add-hook 'org-babel-after-execute-hook 'semacs/ob-args-ext-session-reset)

(defun semacs/ob-args-ext-session-reset()
  (let* ((src-block-info (org-babel-get-src-block-info 'light))
         (language (nth 0 src-block-info))
         (arguments (nth 2 src-block-info))
         (should-reset (member '(:session-reset . "yes") arguments))
         (session (cdr (assoc :session arguments)))
         (session-process
          (cond ((equal language "elixir") (format "*elixir-%s*" session))
                (t nil))))
    (if (and should-reset (get-process session-process))
        (kill-process session-process))))

Setelah mengevaluasi kode di atas, Anda dapat menulis blok src seperti ini:

#+begin_src elixir :session-reset yes
  IO.puts("HELLO WORLD")
#+end_src

Setelah mengevaluasi blok src, org-babel akan membersihkan sesi yang sesuai.


sumber