aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/org/ob-R.el
diff options
context:
space:
mode:
authorKyle Meyer2021-09-29 18:48:59 -0400
committerKyle Meyer2021-09-29 23:21:21 -0400
commitbf9ec3d91a79414deac039f7bf83352a9b0a9a85 (patch)
tree5e636992801ca408a26f7b7532c666d24c80020e /lisp/org/ob-R.el
parentdc94ca7b2b878c9a88be72fea118bf6557259ffd (diff)
downloademacs-bf9ec3d91a79414deac039f7bf83352a9b0a9a85.tar.gz
emacs-bf9ec3d91a79414deac039f7bf83352a9b0a9a85.zip
Update to Org 9.5
Diffstat (limited to 'lisp/org/ob-R.el')
-rw-r--r--lisp/org/ob-R.el122
1 files changed, 111 insertions, 11 deletions
diff --git a/lisp/org/ob-R.el b/lisp/org/ob-R.el
index 309a0acf7e7..169e1d6d6ce 100644
--- a/lisp/org/ob-R.el
+++ b/lisp/org/ob-R.el
@@ -4,6 +4,7 @@
4 4
5;; Author: Eric Schulte 5;; Author: Eric Schulte
6;; Dan Davison 6;; Dan Davison
7;; Maintainer: Jeremie Juste
7;; Keywords: literate programming, reproducible research, R, statistics 8;; Keywords: literate programming, reproducible research, R, statistics
8;; Homepage: https://orgmode.org 9;; Homepage: https://orgmode.org
9 10
@@ -39,6 +40,13 @@
39(declare-function ess-wait-for-process "ext:ess-inf" 40(declare-function ess-wait-for-process "ext:ess-inf"
40 (&optional proc sec-prompt wait force-redisplay)) 41 (&optional proc sec-prompt wait force-redisplay))
41 42
43;; FIXME: Temporary declaration to silence the byte-compiler
44(defvar user-inject-src-param)
45(defvar ess-eval-visibly-tmp)
46(defvar ess-eval-visibly)
47(defvar ess-inject-source)
48(defvar user-inject-src-param)
49
42(defconst org-babel-header-args:R 50(defconst org-babel-header-args:R
43 '((width . :any) 51 '((width . :any)
44 (height . :any) 52 (height . :any)
@@ -157,6 +165,7 @@ This function is called by `org-babel-execute-src-block'."
157 (save-excursion 165 (save-excursion
158 (let* ((result-params (cdr (assq :result-params params))) 166 (let* ((result-params (cdr (assq :result-params params)))
159 (result-type (cdr (assq :result-type params))) 167 (result-type (cdr (assq :result-type params)))
168 (async (org-babel-comint-use-async params))
160 (session (org-babel-R-initiate-session 169 (session (org-babel-R-initiate-session
161 (cdr (assq :session params)) params)) 170 (cdr (assq :session params)) params))
162 (graphics-file (and (member "graphics" (assq :result-params params)) 171 (graphics-file (and (member "graphics" (assq :result-params params))
@@ -183,7 +192,8 @@ This function is called by `org-babel-execute-src-block'."
183 (cdr (assq :colname-names params)) colnames-p)) 192 (cdr (assq :colname-names params)) colnames-p))
184 (or (equal "yes" rownames-p) 193 (or (equal "yes" rownames-p)
185 (org-babel-pick-name 194 (org-babel-pick-name
186 (cdr (assq :rowname-names params)) rownames-p))))) 195 (cdr (assq :rowname-names params)) rownames-p))
196 async)))
187 (if graphics-file nil result)))) 197 (if graphics-file nil result))))
188 198
189(defun org-babel-prep-session:R (session params) 199(defun org-babel-prep-session:R (session params)
@@ -321,7 +331,7 @@ Each member of this list is a list with three members:
321 (device-info (or (assq (intern (concat ":" device)) 331 (device-info (or (assq (intern (concat ":" device))
322 org-babel-R-graphics-devices) 332 org-babel-R-graphics-devices)
323 (assq :png org-babel-R-graphics-devices))) 333 (assq :png org-babel-R-graphics-devices)))
324 (extra-args (cdr (assq :R-dev-args params))) filearg args) 334 (extra-args (cdr (assq :R-dev-args params))) filearg args)
325 (setq device (nth 1 device-info)) 335 (setq device (nth 1 device-info))
326 (setq filearg (nth 2 device-info)) 336 (setq filearg (nth 2 device-info))
327 (setq args (mapconcat 337 (setq args (mapconcat
@@ -348,7 +358,7 @@ Each member of this list is a list with three members:
348 { 358 {
349 tfile<-tempfile() 359 tfile<-tempfile()
350 write.table(object, file=tfile, sep=\"\\t\", 360 write.table(object, file=tfile, sep=\"\\t\",
351 na=\"nil\",row.names=%s,col.names=%s, 361 na=\"\",row.names=%s,col.names=%s,
352 quote=FALSE) 362 quote=FALSE)
353 file.rename(tfile,transfer.file) 363 file.rename(tfile,transfer.file)
354 }, 364 },
@@ -370,11 +380,14 @@ Has four %s escapes to be filled in:
3704. The name of the file to write to") 3804. The name of the file to write to")
371 381
372(defun org-babel-R-evaluate 382(defun org-babel-R-evaluate
373 (session body result-type result-params column-names-p row-names-p) 383 (session body result-type result-params column-names-p row-names-p async)
374 "Evaluate R code in BODY." 384 "Evaluate R code in BODY."
375 (if session 385 (if session
376 (org-babel-R-evaluate-session 386 (if async
377 session body result-type result-params column-names-p row-names-p) 387 (ob-session-async-org-babel-R-evaluate-session
388 session body result-type result-params column-names-p row-names-p)
389 (org-babel-R-evaluate-session
390 session body result-type result-params column-names-p row-names-p))
378 (org-babel-R-evaluate-external-process 391 (org-babel-R-evaluate-external-process
379 body result-type result-params column-names-p row-names-p))) 392 body result-type result-params column-names-p row-names-p)))
380 393
@@ -450,11 +463,13 @@ last statement in BODY, as elisp."
450 (car (split-string line "\n"))) 463 (car (split-string line "\n")))
451 (substring line (match-end 1)) 464 (substring line (match-end 1))
452 line)) 465 line))
453 (org-babel-comint-with-output (session org-babel-R-eoe-output) 466 (with-current-buffer session
454 (insert (mapconcat 'org-babel-chomp 467 (let ((comint-prompt-regexp (concat "^" comint-prompt-regexp)))
455 (list body org-babel-R-eoe-indicator) 468 (org-babel-comint-with-output (session org-babel-R-eoe-output)
456 "\n")) 469 (insert (mapconcat 'org-babel-chomp
457 (inferior-ess-send-input)))))) "\n")))) 470 (list body org-babel-R-eoe-indicator)
471 "\n"))
472 (inferior-ess-send-input)))))))) "\n"))))
458 473
459(defun org-babel-R-process-value-result (result column-names-p) 474(defun org-babel-R-process-value-result (result column-names-p)
460 "R-specific processing of return value. 475 "R-specific processing of return value.
@@ -465,6 +480,91 @@ Insert hline if column names in output have been requested."
465 (error "Could not parse R result")) 480 (error "Could not parse R result"))
466 result)) 481 result))
467 482
483
484;;; async evaluation
485
486(defconst ob-session-async-R-indicator "'ob_comint_async_R_%s_%s'")
487
488(defun ob-session-async-org-babel-R-evaluate-session
489 (session body result-type _ column-names-p row-names-p)
490 "Asynchronously evaluate BODY in SESSION.
491Returns a placeholder string for insertion, to later be replaced
492by `org-babel-comint-async-filter'."
493 (org-babel-comint-async-register
494 session (current-buffer)
495 "^\\(?:[>.+] \\)*\\[1\\] \"ob_comint_async_R_\\(.+?\\)_\\(.+\\)\"$"
496 'org-babel-chomp
497 'ob-session-async-R-value-callback)
498 (cl-case result-type
499 (value
500 (let ((tmp-file (org-babel-temp-file "R-")))
501 (with-temp-buffer
502 (insert
503 (org-babel-chomp body))
504 (let ((ess-local-process-name
505 (process-name (get-buffer-process session))))
506 (ess-eval-buffer nil)))
507 (with-temp-buffer
508 (insert
509 (mapconcat
510 'org-babel-chomp
511 (list (format org-babel-R-write-object-command
512 (if row-names-p "TRUE" "FALSE")
513 (if column-names-p
514 (if row-names-p "NA" "TRUE")
515 "FALSE")
516 ".Last.value"
517 (org-babel-process-file-name tmp-file 'noquote))
518 (format ob-session-async-R-indicator
519 "file" tmp-file))
520 "\n"))
521 (let ((ess-local-process-name
522 (process-name (get-buffer-process session))))
523 (ess-eval-buffer nil)))
524 tmp-file))
525 (output
526 (let ((uuid (md5 (number-to-string (random 100000000))))
527 (ess-local-process-name
528 (process-name (get-buffer-process session))))
529 (with-temp-buffer
530 (insert (format ob-session-async-R-indicator
531 "start" uuid))
532 (insert "\n")
533 (insert body)
534 (insert "\n")
535 (insert (format ob-session-async-R-indicator
536 "end" uuid))
537 (setq ess-eval-visibly-tmp ess-eval-visibly)
538 (setq user-inject-src-param ess-inject-source)
539 (setq ess-eval-visibly nil)
540 (setq ess-inject-source 'function-and-buffer)
541 (ess-eval-buffer nil))
542 (setq ess-eval-visibly ess-eval-visibly-tmp)
543 (setq ess-inject-source user-inject-src-param)
544 uuid))))
545
546(defun ob-session-async-R-value-callback (params tmp-file)
547 "Callback for async value results.
548Assigned locally to `ob-session-async-file-callback' in R
549comint buffers used for asynchronous Babel evaluation."
550 (let* ((graphics-file (and (member "graphics" (assq :result-params params))
551 (org-babel-graphical-output-file params)))
552 (colnames-p (unless graphics-file (cdr (assq :colnames params)))))
553 (org-babel-R-process-value-result
554 (org-babel-result-cond (assq :result-params params)
555 (with-temp-buffer
556 (insert-file-contents tmp-file)
557 (org-babel-chomp (buffer-string) "\n"))
558 (org-babel-import-elisp-from-file tmp-file '(16)))
559 (or (equal "yes" colnames-p)
560 (org-babel-pick-name
561 (cdr (assq :colname-names params)) colnames-p)))))
562
563
564
565;;; ob-session-async-R.el ends here
566
567
468(provide 'ob-R) 568(provide 'ob-R)
469 569
470;;; ob-R.el ends here 570;;; ob-R.el ends here