Org babel async yürütme


14

Org-babel'in zaman uyumsuz olarak çalışması için iyi bir genel özelleştirmesi var mı? Son zamanlarda MATLAB'ı org-babel ile kullanmayı planlıyorum, ancak bazı hesaplamalar zaman aldığı için zaman uyumsuz bir şekilde istiyorum.

Sadece ob-matlab'ı özelleştirmek istemiyorum. Bunun bir uygulama yerine çerçeve düzeyinde yapılması gerektiğini düşünüyorum. Başka bir deyişle, aynı modifikasyon, R dili gibi diğer dil uzantıları için zaman uyumsuzluk özelliğini etkinleştirmelidir.

İyi bir çözümü olan var mı? Şimdiye kadar ben denedim async.elyanı sıra deferred.eldeğiştirmek için org-babel-execute-safely-maybebu bulunabilir ob-core.elanda.


Başka bir ipucu babel bloğunu ekrana veya tmux'a geçirebilir.
stardiviner

Bunu hiç uygulamadım, ama kulağa mümkün geliyor. Teşekkürler.
diadochos

Sanırım son bir aydır gönderilen başka bir çözüm olmadığından kendi cevabımı kabul ediyorum.
diadochos

Yanıtlar:


6

Şimdiye kadar yeni bir Emacs süreci yaratmanın bir çözüm olduğunu keşfettim.

İşte yaptığım şey.

1. Harici emacs işlemini başlatmak için bir işlev ekleyin.

init.el

(defvar my/async-emacs-repl-org-babel-init-file "~/.emacs.d/org-babel-async-init" "File to load on executing async babel evaluation.")

(defun my/async-emacs-repl--start (process-name init-file)
  "Start a new Emacs process as a REPL server."
  (async-shell-command (concat
                        "TERM=vt200 emacs --batch -nw"
                        " --eval '(load \"" init-file "\")'"
                        " --eval '(while t (print (eval (read))))'"
                        )
                       process-name))

(defun my/async-emacs-repl--org-babel--start-server ()
  "Starts an Emacs process for async org-babel execution."
  (my/async-emacs-repl--start "*org-babel-async*" my/async-emacs-repl-org-babel-init-file))

(defun my/async-emacs-repl--org-babel--start-if-not-exists ()
  "Starts an Emacs process if the process does not exist."
  (if (not (get-buffer-process "*org-babel-async*")) (my/async-emacs-repl--org-babel--start-server)))

(defun my/async-emacs-repl--org-babel--execute--build-command (file-name line-number)
  "Build the command for executing `org-babel-execute-src-block'."
  (concat
   "(progn"
   " (find-file \"" file-name "\")"
   " (revert-buffer t t)"
   " (goto-line " (number-to-string line-number) ")"
   " (org-babel-execute-src-block t)"
   " (save-buffer)"
   ")"
   "\n"))

(defun my/async-emacs-repl--org-babel--execute (process-name file-name line-number)
  "Sends the command to the server to run the code-block the cursor is at."
  (process-send-string
   process-name
   (my/async-emacs-repl--org-babel--execute--build-command file-name line-number)))

(defun my/async-emacs-repl-org-babel-do-execute ()
  "Run org babel execution at point."
  (my/async-emacs-repl--org-babel--execute "*org-babel-async*" (buffer-file-name) (line-number-at-pos)))

(defun my/async-emacs-repl-org-babel-execute ()
  "Run by the user. Executes command. Starts buffer if not exists."
  (interactive)
  (save-buffer)
  (my/async-emacs-repl--org-babel--start-if-not-exists)
  (my/async-emacs-repl-org-babel-do-execute))

2. Yeni emacs işlemine yüklenecek bir yapılandırma dosyası ekleyin.

Yukarıdaki fonksiyon emacları --batchmodda başlatır . Böylece normal init.el yüklenmeyecektir.

Bunun yerine, daha kısa bir yapılandırma dosyası oluşturmak istiyoruz (yolları yüklemek vb.).

Yeni yapılandırma dosyamızın yolu async-emacs-repl-org-babel-init-fileyukarıdaki snippet'te saklanır .

org babel zaman uyumsuz-init.el

;; 1
(package-initialize)

;; 2
(setq org-confirm-babel-evaluate nil)

;; 3
(let ((my/org-babel-evaluated-languages
       '(emacs-lisp
         ditaa
         python
         ruby
         C
         matlab
         clojure
         sh
         dot
         plantuml)))
  (org-babel-do-load-languages
   'org-babel-load-languages
   (mapcar (lambda (lang)
             (cons lang t))
           my/org-babel-evaluated-languages)))

İşte ...

  1. Paket yolları ekleyin.
  2. Kuruluş kipine kod bloğu yürütülüp yürütülmeyeceğini sormamasını söyleyin.
  3. Org-babel'e hangi dillerin gerekli olduğunu söyleyin.

Dipnot 1: Bu ayar olmadan değerlendirme başarısız olur "No org-babel-execute function for $lang!"

Dipnot 2: İsterseniz, yeni bir yapılandırma dosyası oluşturmak yerine normal init.el dosyasını yükleyebilirsiniz. Bunu, hesabınıza ekleyerek (setq org-babel-async-init-file "~/.emacs.d/init")yapın init.el. Ancak bu görev için bir yapılandırma dosyası oluşturmanın daha basit olduğunu düşünüyorum.

3. Ayrıca ...

İnit.el'e ekle

;; This will stop the new process buffer from getting focus.
(setq display-buffer-alist (append display-buffer-alist '(("*org-babel-async*" display-buffer-no-window))))

;; This will automatically show the result section.
(global-auto-revert-mode 1)

Ekle org-babel-async-init.el

;; This will skip the "Save anyway?" confirmation of automatically saving the file when you also edited the buffer from Emacs while an asynchronous process is running.
(defun advice:verify-visited-file-modtime (orig-func &rest args) t)
(advice-add 'verify-visited-file-modtime :around 'advice:verify-visited-file-modtime)

;; This will skip the "Select coding system" prompt that appears when the result is inserted. This may vary among environments.
(setq coding-system-for-write 'utf-8)

;; This will skip the "changed on disk; really edit the buffer?" checking.
(defun ask-user-about-supersession-threat (fn) "blatantly ignore files that changed on disk")

Ekle org-babel-zaman uyumsuz-init.el (bu gerekmeyebilir. Bunlar MATLAB içindir)

;; This will set MATLAB cli path.
(setq-default matlab-shell-command "/Applications/MATLAB_R2016a.app/bin/matlab")
;; The MATLAB cli path can be obtained by running `fullfile(matlabroot, 'bin')` in your MATLAB.

;; This will stop MATLAB from showing the splash (the MATLAB logo) at the beginning.
(setq-default matlab-shell-command-switches '("-nodesktop" "-nosplash"))

Ekle org-babel-zaman uyumsuz-init.el (bu gerekmeyebilir. Bunlar Julia, R ve kullanım ESS diğer diller için vardır.)

;; This will enable :session header in Julia and other languages that use ESS (Emacs speaks statistics).
(load "/path/to/ess-site")
;; This will suppress ESS from prompting for session directory.
(setq ess-ask-for-ess-directory nil)

4. Kullanım

(Yukarıdaki kurulumdan sonra.)

  1. İmleci yürütmek istediğiniz kod parçacığına getirin.
  2. Çalıştır M-x my/async-emacs-repl-org-babel-execute(yapmak yerine C-c C-c). Bu, gerekirse harici bir Emacs işlemini REPL sunucusu olarak başlatır ve ardından bulunduğunuz kaynak bloğu yürütür.

Teşekkür

Ben gelen org-babel değerlendirilmesi için emacs işlemine başlamadan fikrini öğrendik bu yazı . Yazara teşekkür etmek istiyorum.

Özelleştirme için yorumlar

Buradaki fikir basit. Yeni bir emacs yapmak, elisp için repl olarak işlemek başlayın find-file, biz düzenlediğiniz aynı .org dosyaya goto-linekoşmak aynı imlecin bulunduğu noktaya, için org-babel-execute-src-block, save-buffer. Kullanıcı işlemi durdurana kadar çıkmayı bırakın (Aksi takdirde, grafikler gösterildikten hemen sonra kaybolacaktır). Doğal olarak bunu şu şekilde genişletmeyi düşünebiliriz:

  • C-c C-cFonksiyonları elle çalıştırmak yerine org- mode'ları kullanmak / yeni bir tuş takımı ayarlamak (önerilerle elde edilebilir).
  • İşlem adını şuna göre koşullu olarak değiştirme: oturum değişkeni ve dil
  • İnit dosyalarını dile bağlı olarak koşullu olarak değiştirme.

Aslında, bu yaklaşımın başarısı bana Emacs'ta asenk özellikler geliştirmenin genel bir yolunu gösteriyor gibi görünüyor. "Komutlar" katmanı oluşturma, görevler için komut dosyaları ekleme ve emacs işlemlerini başlatma ve yeniden kullanma için bir çerçeve oluşturma. PHP'nin Symfony çerçevesi gibi (PHP'nin konuları yoktur) Komut özelliklerine sahiptir.

Geçmişi düzenle

Yeniden düzenlenmiş kod (2016-04-02). Çözüm artık bir Emacs sürecini yeniden kullanıyor (2016-04-02). Çözüm artık basitleştirilmiş ve interactiveçalıştırılacak tek bir komutu var (2016-04-02. Eklenen yapılandırma (2016-04-12).


Gördün async.el
PythonNut

Evet bende var. Esasen Emacs'ın yeni bir sürecini başlatır ve lambdaona verilen işlevi çalıştırır . Bu işlem için kullanmadım çünkü yeni sürece veri göndermenin bir yolunu bulamadım. Org-babel'in: session özelliğini kullanmak istiyorsanız, işlemin iletilmesi gerekir.
diadochos

Bu çözüm üzerinde çalıştığınız için teşekkürler. Denedim ama bu hata iletisini alıyorum: TERM=vt200 emacs --batch -nw --eval '(load "~/.emacs.d/org-babel-async-init")' --eval '(while t (print (eval (read))))': exited abnormally with code 255.Üzgünüm, bu bir yorum olmalı ve bir cevap değil, ama yeterli puanım yok.
mhartm

Bunu yaptıktan sonra " org-babel-async " adlı bir arabellek görüyor musunuz? Bir tane bulabilirseniz, bu arabellek muhtemelen hata hakkında daha fazla bilgi içerir. "Kod 255 ile anormal olarak çıkıldı" genellikle ortaya çıkan emacs işleminde çalıştırmak istediğiniz program başarısız olduğunda oluşur. Olası çözümler: 1) / async-emacs-repl-org-babel-init-dosyamda belirtilen dosyanın olup olmadığını kontrol edin. Bunu yapmazsanız, yukarıda açıklandığı gibi bir tane oluşturun. 2) Kullanmak istediğiniz dili listelediğinizden emin olun org-babel-do-load-languages. 3) #+SRC_BEGINYürüttüğünüz blok bir hata içeriyor.
diadochos

Sorunum çalıştırmadan önce benim org dosyayı kaydetmek gerekir bu yüzden Tamam, M-x my/async-emacs-repl-org-babel-executeaksi "org-babel-zaman uyumsuz" tampon şikayet: ...t/Dropbox/org/work.org locked by maarhart@htkl... (pid 68694): (s, q, p, ?)? Please type q, s, or p; or ? for help. Eğer bu çözülebilirse, harika olurdu. Yine de bunun için teşekkürler, inanılmaz! Bu arada, onu C-c C-corg moduna bağlamak ya da çatışmak mümkün mü?
mhartm

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.