Làm thế nào để buộc một phiên org-babel để thiết lập lại hoặc khởi tạo?


8

Nếu tôi chạy các khối vỏ babel sau đây

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

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

Org tạo một bộ đệm shell được gọi one, chạy ssh stagingvà sau đó sau khi kết nối, thực hiện hostnametrên dàn. Tuy nhiên, nếu tôi điều chỉnh lệnh ssh và chạy lại, nó sẽ cố chạy nó từ trong phiên một, từ máy chủ dàn. Nếu tôi đóng bộ đệm, onenó sẽ thiết lập lại phiên như lần sau khi bất kỳ lệnh nào được chạy với tên phiên đó, nó sẽ tạo lại nó. Điều tôi chưa thể tìm thấy là một phương pháp để buộc một khối babel cụ thể luôn luôn khởi tạo một phiên mới.

Tôi biết rằng đối với một số ngôn ngữ (đặc biệt là elisp) thì điều này là không thể. Tôi cho rằng tôi có thể đặt trước phiên với một khối elisp có chứa (kill-buffer "one"), nhưng thay vào đó, đây là một đối số tiêu đề nếu có thể. Tôi cũng biết rằng với ví dụ này, tôi chỉ có thể kết hợp cả hai thành một khối duy nhất mà không có phiên nào, nhưng tôi quan tâm đến các chuỗi phức tạp hơn.

Có một :prologuelệnh hoặc một số đối số đặc biệt nào khác để :sessionbuộc các khối đó khởi tạo một lớp vỏ mới trên mỗi lệnh gọi không?


Không có tùy chọn như vậy (hoặc tham số khối mã nguồn) trong Org 8.2.10, nhưng nó khá dễ dàng để thêm. Tôi sẽ bắt đầu bằng cách hack org-babel-initiate-session.
Constantine

Câu trả lời:


5

Thử cái này

Buộc phiên org-babel để đặt lại hoặc khởi tạo bằng cách sử dụng câu lệnh có điều kiện elisp để tự động đặt giá trị của tiêu đề : phiên trên khối mã đầu tiên.

ví dụ :session (if (get-buffer "one") (if (kill-buffer "one") (print "one") (print "one")) (print "one"))

Trong đoạn mã trên, get-đệm kiểm tra chức năng nếu đệm tên là một tồn tại. Nếu đúng, các kill-buffer chức năng tiêu diệt các một bộ đệm sau đó trả về một giá trị thoặc nilđược truyền cho iftuyên bố. Trong ví dụ cụ thể này, ifcâu lệnh lồng nhau sẽ luôn trả về giá trị của một . Xin lưu ý, tôi vẫn đang học elisp.

Dưới đây là mã ví dụ cập nhật:

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

Mỗi khi khối mã đầu tiên được thực thi, emacs sẽ yêu cầu hủy một bộ đệm , do đó bạn có thể đặt lại phiên khi bạn muốn.

BIÊN TẬP

Rất tiếc một phần mà bạn luôn muốn bộ đệm bị giết, tức là không có dấu nhắc . Thực hiện khối này trước để tạm thời tắt nhắc nhở để giết bộ đệm.

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

Hy vọng rằng đã giúp!

Lưu ý: Mã này đã được kiểm tra bằng các phiên bản sau của emacs và chế độ org.

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)

Để kết luận, tôi đã tìm thấy cảm hứng kỹ thuật cho câu trả lời này trên trang web org-scrapsmã ví dụ kill-buffer này trên stackoverflow.


@dgtized đã làm câu trả lời này giúp?
Melioratus

2
Tôi không biết bạn có thể nhúng elisp trong cuộc gọi phiên, vì vậy cảm ơn bạn vì điều đó. Điều đó nói rằng, như tôi đã đề cập trong câu hỏi ban đầu, tôi biết rằng tôi có thể tự động hóa kill-bufferđể buộc một phiên mới, nhưng quan tâm hơn đến việc học nếu có một đối số khối được xây dựng ở chế độ org hoặc một số quy ước được thiết lập khác để thực hiện điều này mà tôi đã không nhận thức được. Cách tiếp cận của bạn là một cách giải quyết tốt, nhưng tôi hy vọng có một cách tiếp cận kinh điển cho việc này.
dgtized

@dgtized - Bạn đang tìm kiếm một câu trả lời như thế này? :session one :session-reset yes?
Melioratus

Một cái gì đó như thế chắc chắn. Một lần nữa, đó là một câu hỏi về thực hành được đề xuất cho ví dụ này. Chắc chắn những người khác có các phiên cần thiết lập lại, và nếu họ chỉ giết bộ đệm thì tốt, nhưng tôi muốn biết thực hành tiêu chuẩn là gì.
48 phút

@dgtized - Cảm ơn đã làm rõ! Đây là câu hỏi tuyệt vời! Tôi đã không tìm thấy một thực hành tiêu chuẩn tài liệu nhưng tôi sẽ tiếp tục tìm kiếm .
Melioratus

2

Lấy cảm hứng từ @Melioratus.

Hiện tại, org-babel cung cấp một hook được gọi là org-babel-after-execute-hook. Tôi đã mở rộng các đối số được hỗ trợ của khối src org-babel bằng cách sử dụng nó:

(Tôi đang sử dụng org-babel cho thuốc tiên. Nếu bạn muốn hỗ trợ các ngôn ngữ khác, condhãy tự mình mở rộng .)

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

Sau khi đánh giá mã trên, bạn có thể viết khối src như thế này:

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

Sau khi đánh giá khối src, org-babel sẽ dọn sạch phiên tương ứng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.