From 1b39a64fbe533b326be747342c9ce7f3948dde1c Mon Sep 17 00:00:00 2001 From: Eric Schulte Date: Sun, 14 Jun 2009 11:08:12 -0700 Subject: [PATCH] ruby blocks can now pop to session buffer (optionally evaluating header-args) --- lisp/langs/org-babel-ruby.el | 20 ++++++++++++++++++-- lisp/org-babel-comint.el | 6 +++--- lisp/org-babel.el | 29 +++++++++++++++++++++++++++++ org-babel.org | 14 ++++++++++++-- 4 files changed, 62 insertions(+), 7 deletions(-) diff --git a/lisp/langs/org-babel-ruby.el b/lisp/langs/org-babel-ruby.el index a1ca2ee44..bbe043bc9 100644 --- a/lisp/langs/org-babel-ruby.el +++ b/lisp/langs/org-babel-ruby.el @@ -60,6 +60,24 @@ called by `org-babel-execute-src-block'." (org-babel-import-elisp-from-file tmp-file))) ('value (org-babel-ruby-table-or-results results)))))) +(defun org-babel-prep-session:ruby (session params) + "Prepare SESSION according to the header arguments specified in PARAMS." + (message "prep called with %S %S" session params) + (let* ((session (org-babel-ruby-initiate-session session)) + (vars (org-babel-ref-variables params)) + (var-lines (mapcar ;; define any variables + (lambda (pair) + (format "%s=%s" + (car pair) + (org-babel-ruby-var-to-ruby (cdr pair)))) + vars))) + (org-babel-comint-in-buffer session + (mapc (lambda (var) + (insert var) (comint-send-input nil t) + (org-babel-comint-wait-for-output session)) var-lines)))) + +;; helper functions + (defun org-babel-ruby-var-to-ruby (var) "Convert an elisp var into a string of ruby source code specifying a var of the same value." @@ -80,8 +98,6 @@ Emacs-lisp table, otherwise return the results as a string." "'" "\"" results))))) results))) -;; functions for comint evaluation - (defun org-babel-ruby-initiate-session (&optional session) "If there is not a current inferior-process-buffer in SESSION then create. Return the initialized session." diff --git a/lisp/org-babel-comint.el b/lisp/org-babel-comint.el index b21ebb84e..9e068743c 100644 --- a/lisp/org-babel-comint.el +++ b/lisp/org-babel-comint.el @@ -47,9 +47,9 @@ body inside the protection of `save-window-excursion' and (declare (indent 1)) `(save-window-excursion (save-match-data - (unless (org-babel-comint-buffer-livep buffer) - (error (format "buffer %s doesn't exist or has no process" buffer))) - (set-buffer buffer) + (unless (org-babel-comint-buffer-livep ,buffer) + (error (format "buffer %s doesn't exist or has no process" ,buffer))) + (set-buffer ,buffer) ,@body))) (defmacro org-babel-comint-with-output (buffer eoe-indicator remove-echo &rest body) diff --git a/lisp/org-babel.el b/lisp/org-babel.el index 0a44a4dc2..650952548 100644 --- a/lisp/org-babel.el +++ b/lisp/org-babel.el @@ -40,6 +40,15 @@ then run `org-babel-execute-src-block'." (add-hook 'org-ctrl-c-ctrl-c-hook 'org-babel-execute-src-block-maybe) +(defun org-babel-pop-to-session-maybe () + "Detect if this is context for a org-babel src-block and if so +then run `org-babel-pop-to-session'." + (interactive) + (let ((info (org-babel-get-src-block-info))) + (if info (progn (org-babel-pop-to-session current-prefix-arg info) t) nil))) + +(add-hook 'org-metadown-hook 'org-babel-pop-to-session-maybe) + (defvar org-babel-default-header-args '() "Default arguments to use when evaluating a source block.") @@ -102,6 +111,26 @@ lisp code use the `org-babel-add-interpreter' function." (const "ruby"))) ;;; functions +(defun org-babel-pop-to-session (&optional arg info) + "Pop to the session of the current source-code block. If +called with a prefix argument then evaluate the header arguments +for the source block before entering the session. Copy the body +of the source block to the kill ring." + (interactive) + (let* ((info (or info (org-babel-get-src-block-info))) + (lang (first info)) + (body (second info)) + (params (third info)) + (session (cdr (assoc :session params)))) + (unless (member lang org-babel-interpreters) + (error "Language is not in `org-babel-interpreters': %s" lang)) + ;; copy body to the kill ring + (with-temp-buffer (insert body) (copy-region-as-kill (point-min) (point-max))) + ;; if called with a prefix argument, then process header arguments + (if arg (funcall (intern (concat "org-babel-prep-session:" lang)) session params)) + ;; just to the session using pop-to-buffer + (pop-to-buffer (funcall (intern (format "org-babel-%s-initiate-session" lang)) session)))) + (defun org-babel-execute-src-block (&optional arg info params) "Execute the current source code block, and dump the results into the buffer immediately following the block. Results are diff --git a/org-babel.org b/org-babel.org index b8230aec2..3a901a054 100644 --- a/org-babel.org +++ b/org-babel.org @@ -122,7 +122,7 @@ and the results to be collected in the same table. At the same time I introduced org-babel-named-src-block-regexp, to match src-blocks with srcname. -** TODO Create objects in top level (global) environment [3/5] +** TODO Create objects in top level (global) environment [3/9] *sessions* *** initial requirement statement [DED] @@ -664,7 +664,7 @@ a + b a + b #+end_src -*** TODO function to bring up inferior-process buffer +*** TODO function to bring up inferior-process buffer [1/4] This should be callable from inside of a source-code block in an org-mode buffer. It should evaluate the header arguments, then bring @@ -673,6 +673,16 @@ up the inf-proc buffer using =pop-to-buffer=. For lack of a better place, lets add this to the `org-shiftmetadown-hook' hook. +**** DONE ruby + +#+srcname: task-ruby-pop-to-session +#+begin_src ruby :var num=9 :var another="something else" +num.times{|n| puts n} +#+end_src + +**** TODO R +**** TODO python +**** TODO shell *** TODO function to dump last N lines from inf-proc buffer into the current source block Callable with a prefix argument to specify how many lines should be