Làm cách nào tôi có thể đánh giá elisp trong tệp orgmode khi nó được mở?


13

Tôi có mã elisp tôi muốn chạy trong các tệp orgmode khi chúng tải (khác nhau cho các tệp khác nhau và được xác định trong chính tệp). Có cách nào để làm việc này không? Tôi đã không thấy bất cứ điều gì trong http://orgmode.org/manual/In_002dbuffer-sinstall.html

Nếu tôi có thể thêm một cái gì đó vào việc khởi tạo emacs chạy một khối mã có tên đặc biệt mỗi khi tải tệp orgmode, đó có thể là một giải pháp, nhưng tôi không chắc làm thế nào để làm điều đó, và lý tưởng là có một cái gì đó được tích hợp.


1
Biến tệp cục bộ, có lẽ?
Dân

Đó là công việc! Bạn có muốn biến nó thành một câu trả lời mà tôi có thể chấp nhận không?
avv

Theo suy nghĩ thêm rằng đó là một môi trường rất lộn xộn để chỉnh sửa, vì vậy một giải pháp tốt sẽ có biến cục bộ tệp chạy một khối mã được đặt tên.
avv

Bọc nó trong một progn hoặc lambda, có lẽ?
Dan

3
Bạn cũng có thể sử dụng # -*- eval: (lisp code here) -*-nhưng bạn cũng phải nhận thức được những nguy hiểm. Ngay cả khi bạn không chia sẻ các tài liệu này với bất kỳ ai khác, bản chất được giải thích của Emacs Lisp sẽ có nghĩa là một thay đổi có thể vô tình dẫn đến mất dữ liệu. Ngoài ra, hook hook có vẻ như là một tùy chọn tốt hơn nếu bạn muốn chạy cùng một mã cho nhiều hơn một tệp.
wvxvw

Câu trả lời:


9

Giải pháp này không yêu cầu thay đổi init.el(với sửa đổi nhỏ). Tuy nhiên, nó liên quan đến các đánh giá tệp cục bộ - nhưng đó chính xác là những gì OP yêu cầu. Ưu điểm của giải pháp là:

  • yêu cầu xác nhận để đánh giá mã
  • mã elisp có thể được chỉnh sửa và kiểm tra trong môi trường org-babel
  • vì giải pháp không yêu cầu sửa đổi init.eltệp orgmode có thể được chia sẻ giữa những người dùng (đáng tin cậy)

Tôi đang xem xét lại giải pháp ở đây.

Thêm một khối src ở đâu đó trong tệp của bạn:

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

Sau đó, đặt phần này vào cuối tệp orgmode của bạn:

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

Tôi đã thêm vào (outline-hide-sublevels 1)vì tôi muốn ẩn khối src bên trong một tiêu đề và muốn các cấp dưới bị ẩn khi khởi động. Không có tuyên bố này, các cấp dưới sẽ được mở rộng bằng (org-babel-goto-named-src-block "startup").

Với giải pháp này, emacs sẽ yêu cầu 2 lần cho phép thực thi (lần 1: áp dụng biến cục bộ; lần 2: thực hiện "khởi động" -src-block). Vì tôi có rất nhiều khối src trong tệp của mình, tôi đã đặt một biến tệp cục bộ khác org-confirm-babel-evaluate, như sau:

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

Cảnh báo: Với phần bổ sung này, emacs sẽ chỉ nhắc một lần để được phép thực thi - tất cả các khối src trong tệp đó có thể được thực thi mà không cần xác nhận thêm. Như những người khác đã chỉ ra trước đây, hành vi này có thể nguy hiểm và bạn nên rất cẩn thận với cài đặt này.

Tuy nhiên, tôi cho rằng giải pháp này (đặc biệt là phiên bản đầu tiên) an toàn hơn giải pháp do Joe Corneli đưa ra bởi vì ít nhất bạn sẽ được yêu cầu xác nhận để thực thi. Giải pháp của Joe sẽ đánh giá khối đặc biệt mà không cần xác nhận, nếu nó được tìm thấy trong tệp. Kẻ tấn công sẽ phải đoán tên của khối đặc biệt, tất nhiên ...

Tôi đang sử dụng phương pháp này để viết các tài liệu lớn yêu cầu, ví dụ, thích nghi với các cơ chế xuất khẩu org.


5

org-mode... Ngoài bất kỳ hook nào, chế độ cha của nó outline-modecó thể đã chạy, chế độ này chạy hook org-mode-hook, là bước cuối cùng trong quá trình khởi tạo.

Vì vậy, trong init.el của bạn:

(defun function-that-finds-and-evaluates-special-block ()
;; DWIM :-)
)
(add-hook 'org-mode-hook 'function-that-finds-and-evaluates-special-block)

Điều này nghe có vẻ hợp lý với tôi hơn so với các tệp tin cục bộ, cho nhiệm vụ này. Nhưng có lẽ tôi đang thiếu một cái gì đó.
vẽ

@Joe Corneli Và sau đó bạn sẽ đặt gì vào tập tin org thực tế?
sợi đốt

Không có gì đặc biệt ngoại trừ "khối đặc biệt".
Joe Corneli

3

Vì bạn yêu cầu

(khác nhau cho các tệp khác nhau và được xác định trong chính tệp)

Sau đó, thử giải pháp này .


Quan tâm để giải thích tại sao bỏ phiếu xuống?
Người dùng Emacs

Đó là bởi vì câu trả lời chỉ là liên kết đến câu trả lời khác không được khuyến khích. Điều đó đang được nói, có lẽ câu hỏi này là một bản sao của câu hỏi mà bạn liên kết đến?
Linus Arver

1

Tôi đồng ý với đề xuất của @Joe Corneli về việc sử dụng móc.

Tôi cũng biết rằng bạn có thể tận dụng các dấu trang ở đây: đặt một dấu trang cụ thể nhảy lên móc. Một lợi thế của dấu trang đối với khối mã là nó thường được di chuyển tự động (ví dụ như nội dung tệp thay đổi), do đó, việc định vị khối thường được tự động quan tâm.

[Nhưng tôi không rõ tại sao bạn có mã trong các tệp chế độ Org, thay vì ở nơi khác. Chúng tôi đang xem đó là một vấn đề nhất định, theo tuyên bố vấn đề, nhưng tôi tự hỏi tại sao bạn lại làm vậy. Cho chúng tôi biết thêm về thiết kế theo khía cạnh đó có thể dẫn đến sự giúp đỡ tốt hơn.]


0

Tôi đã cố gắng cải thiện mã từ Joe Corneli:

Bạn cần điều đó trong tệp init.el của bạn:

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

Mỗi khi bạn mở bộ đệm chế độ org, nó sẽ tìm kiếm một khối nguồn có tên startblock, nếu tìm thấy một cái, nó sẽ thực thi nó.

Trong các tệp chế độ tổ chức, bạn có thể đặt:

#+NAME: startblock
#+BEGIN_SRC emacs-lisp
  ;; Any code you want
#+END_SRC
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.