From 2d1a5405d11311cd426afeea35751674bb3501ae Mon Sep 17 00:00:00 2001 From: Eric Schulte Date: Wed, 27 May 2009 16:33:22 -0700 Subject: [PATCH 1/6] added task for improving the sb snippet --- org-babel.org | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/org-babel.org b/org-babel.org index 6e522225f..e1b1b4743 100644 --- a/org-babel.org +++ b/org-babel.org @@ -114,7 +114,12 @@ table, allowing the test suite to be run be evaluation of the table and the results to be collected in the same table. -* Tasks [20/28] +* Tasks [20/29] + +** TODO improve the source-block snippet +[[file:~/src/emacs-starter-kit/src/snippets/text-mode/rst-mode/chap::name%20Chapter%20title][file:~/src/emacs-starter-kit/src/snippets/text-mode/rst-mode/chap::name Chapter title]] + + ** TODO resolve references to other buffers This would allow source blocks to call upon tables, source-blocks, From 2c3c91ed125423630b37b6bbe2a3ab506d5a9f37 Mon Sep 17 00:00:00 2001 From: Eric Schulte Date: Wed, 27 May 2009 16:34:48 -0700 Subject: [PATCH 2/6] removed org-babel-ui (tabbing blocks) as the functionality will be included in org-mode core --- lisp/org-babel-init.el | 1 - lisp/org-babel-ui.el | 69 ------------------------------------------ 2 files changed, 70 deletions(-) delete mode 100644 lisp/org-babel-ui.el diff --git a/lisp/org-babel-init.el b/lisp/org-babel-init.el index 0ba3e54ea..9ece9bfde 100644 --- a/lisp/org-babel-init.el +++ b/lisp/org-babel-init.el @@ -34,7 +34,6 @@ (load "htmlize.el") ;; other versions of htmlize can cause export problems (require 'org-babel) (require 'org-babel-ref) -(require 'org-babel-ui) (require 'org-babel-exp) (require 'org-babel-table) diff --git a/lisp/org-babel-ui.el b/lisp/org-babel-ui.el deleted file mode 100644 index 2e8808bd4..000000000 --- a/lisp/org-babel-ui.el +++ /dev/null @@ -1,69 +0,0 @@ -;;; org-babel-ui.el --- UI elements for org-babel - -;; Copyright (C) 2009 Eric Schulte, Dan Davison, Austin F. Frank - -;; Author: Eric Schulte, Dan Davison, Austin F. Frank -;; Keywords: literate programming, reproducible research -;; Homepage: http://orgmode.org -;; Version: 0.01 - -;;; License: - -;; This program is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. -;; -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. - -;;; Commentary: - -;; UI elements of org-babel -;; - code folding -;; - marking working code blocks - -;;; Code: -(require 'org-babel) - -(defun org-babel-ui-src-block-cycle-maybe () - "Detect if this is context for a org-babel src-block and if so -then run `org-babel-execute-src-block'." - (let ((case-fold-search t)) - (if (save-excursion - (beginning-of-line 1) - (looking-at org-babel-src-block-regexp)) - (progn (call-interactively 'org-babel-ui-src-block-cycle) - t) ;; to signal that we took action - nil))) ;; to signal that we did not - -(defun org-babel-ui-src-block-cycle () - "Cycle the visibility of the current source code block" - (interactive) - ;; should really do this once in an (org-mode hook) - (add-to-invisibility-spec '(org-babel-ui . t)) - (message "trying out source block") - (save-excursion - (beginning-of-line) - (if (re-search-forward org-babel-src-block-regexp nil t) - (let ((start (- (match-beginning 4) 1)) ;; beginning of body - (end (match-end 0))) ;; end of entire body - (if (memq t (mapcar (lambda (overlay) - (eq (overlay-get overlay 'invisible) 'org-babel-ui)) - (overlays-at start))) - (remove-overlays start end 'invisible 'org-babel-ui) - (overlay-put (make-overlay start end) 'invisible 'org-babel-ui))) - (error "not looking at a source block")))) - -;; org-tab-after-check-for-cycling-hook -(add-hook 'org-tab-first-hook 'org-babel-ui-src-block-cycle-maybe) - -(provide 'org-babel-ui) -;;; org-babel-ui ends here From aca19b2efc79fe3c4005787644f42953ec941268 Mon Sep 17 00:00:00 2001 From: Eric Schulte Date: Wed, 27 May 2009 16:40:47 -0700 Subject: [PATCH 3/6] added my session thoughts for global variables --- org-babel.org | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/org-babel.org b/org-babel.org index 35483aabe..0cce506f0 100644 --- a/org-babel.org +++ b/org-babel.org @@ -277,6 +277,35 @@ persistent interactive session. It's just that it's particularly natural for R, seeing as both ESS and org-babel evaluate commands in a single persistent R session. +*** sessions [Eric] + +Thanks for bringing this up. I think you are absolutely correct that we +should provide support for a persistent environment (maybe called a +*session*) in which to evaluate code blocks. I think the current setup +demonstrates my personal bias for a functional style of programming +which is certainly not ideal in all contexts. + +While the R function you mention does look like an elegant solution, I +think we should choose an implementation that would be the same across +all source code types. Specifically I think we should allow the user to +specify an optional *session* as a header variable (when not present we +assume a default session for each language). The session name could be +used to name a comint buffer (like the *R* buffer) in which all +evaluation would take place (within which variables would retain their +values --at least once I remove some of the functional method wrappings +currently in place-- ). + +This would allow multiple environments to be used in the same buffer, +and once this setup was implemented we should be able to fairly easily +implement commands for jumping between source code blocks and the +related session buffers, as well as for dumping the last N commands from +a session into a new or existing source code block. + +Please let me know if you foresee any problems with this proposed setup, +or if you think any parts might be confusing for people coming from +Sweave. I'll hopefully find some time to work on this later in the +week. + ** PROPOSED support for passing paths to files between source blocks Maybe this should be it's own result type (in addition to scalars and vectors). The reason being that some source-code blocks (for example From a54c27ec91e0eb09f0bb0f7db85c87063305814f Mon Sep 17 00:00:00 2001 From: Eric Schulte Date: Wed, 27 May 2009 18:42:15 -0700 Subject: [PATCH 4/6] attempts at improving sb snippet --- org-babel.org | 15 ++++++++++++++- snippets/org-mode/sb | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/org-babel.org b/org-babel.org index 0cce506f0..ae741a220 100644 --- a/org-babel.org +++ b/org-babel.org @@ -114,9 +114,22 @@ table, allowing the test suite to be run be evaluation of the table and the results to be collected in the same table. -* Tasks [20/29] +* Tasks [20/32] ** TODO improve the source-block snippet + [[file:~/src/emacs-starter-kit/src/snippets/text-mode/rst-mode/chap::name%20Chapter%20title][file:~/src/emacs-starter-kit/src/snippets/text-mode/rst-mode/chap::name Chapter title]] +#+begin_example +,#name : Chapter title +,# -- +${1:Chapter} +${1:$(make-string (string-width text) ?\=)} + +$0 +#+end_example + +[[file:snippets/org-mode/sb][sb -- snippet]] + +waiting for guidance from those more familiar with yasnippets ** TODO resolve references to other buffers This would allow source blocks to call upon tables, source-blocks, diff --git a/snippets/org-mode/sb b/snippets/org-mode/sb index 4c8f20b3f..48de2e5e2 100644 --- a/snippets/org-mode/sb +++ b/snippets/org-mode/sb @@ -1,6 +1,6 @@ #name : #+begin_src...#+end_src # -- -#+srcname: ${1:name} +${1:$(if (> (length text) 1) "#+srcname:" "")} ${1: } #+begin_src ${2:language} $3 $0 #+end_src From c5a58ad6aa298258bd83d6fd350f43048fd28c18 Mon Sep 17 00:00:00 2001 From: Eric Schulte Date: Wed, 27 May 2009 19:00:13 -0700 Subject: [PATCH 5/6] moving generalized comint functions to new file org-babel-comint.el --- lisp/org-babel-comint.el | 93 ++++++++++++++++++++++++ org-babel.org | 149 ++++++++++++++++++++------------------- 2 files changed, 171 insertions(+), 71 deletions(-) create mode 100644 lisp/org-babel-comint.el diff --git a/lisp/org-babel-comint.el b/lisp/org-babel-comint.el new file mode 100644 index 000000000..2cf301aab --- /dev/null +++ b/lisp/org-babel-comint.el @@ -0,0 +1,93 @@ +;;; org-babel-comint.el --- org-babel functions for interaction with comint buffers + +;; Copyright (C) 2009 Eric Schulte + +;; Author: Eric Schulte +;; Keywords: literate programming, reproducible research, comint +;; Homepage: http://orgmode.org +;; Version: 0.01 + +;;; License: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; This file should provide support for passing commands and results +;; to and from `comint-mode' buffers. + +;;; Code: +(require 'org-babel) + +(defun org-babel-comint-initiate-buffer (buffer ignite) + "If BUFFER does not currently have a process use IGNITE to +create one." + (unless (and (buffer-live-p buffer) (get-buffer buffer)) + (save-excursion + (eval ignite) + (setf buffer (current-buffer)) + (org-babel-comint-wait-for-output) + (org-babel-comint-input-command "")))) + +(defun org-babel-comint-command-to-string (buffer command) + "Send COMMEND to BUFFER's process, and return the results as a string." + (org-babel-comint-input-command buffer command) + (org-babel-comint-last-output buffer)) + +(defun org-babel-comint-input-command (buffer command) + "Pass COMMAND to the process running in BUFFER." + (save-excursion + (save-match-data + (set-buffer buffer) + (goto-char (process-mark (get-buffer-process (current-buffer)))) + (insert command) + (comint-send-input) + (org-babel-comint-wait-for-output)))) + +(defun org-babel-comint-wait-for-output (buffer) + "Wait until output arrives" + (save-excursion + (save-match-data + (set-buffer buffer) + (while (progn + (goto-char comint-last-input-end) + (not (re-search-forward comint-prompt-regexp nil t))) + (accept-process-output (get-buffer-process (current-buffer))))))) + +(defun org-babel-comint-last-output (buffer) + "Return BUFFER's the last output as a string" + (save-excursion + (save-match-data + (set-buffer buffer) + (goto-char (process-mark (get-buffer-process (current-buffer)))) + (forward-line 0) + (let ((raw (buffer-substring comint-last-input-end (- (point) 1))) + output output-flag) + (mapconcat + (lambda (el) + (if (stringp el) + (format "%s" el) + (format "%S" el))) + (delq nil + (mapcar + (lambda (line) + (unless (string-match "^>" line) + (and (string-match "\\[[[:digit:]]+\\] *\\(.*\\)$" line) + (match-string 1 line)))) + ;; drop first, because it's the last line of input + (cdr (split-string raw "[\n\r]")))) "\n"))))) + +;;; org-babel-comint.el ends here diff --git a/org-babel.org b/org-babel.org index ae741a220..76f0f3ae3 100644 --- a/org-babel.org +++ b/org-babel.org @@ -115,6 +115,84 @@ and the results to be collected in the same table. * Tasks [20/32] +** TODO Create objects in top level (global) environment in R? +*** initial requirement statement [DED] + At the moment, objects created by computations performed in the + code block are evaluated in the scope of the + code-block-function-body and therefore disappear when the code + block is evaluated {unless you employ some extra trickery like + assign('name', object, env=globalenv()) }. I think it will be + desirable to also allow for a style wherein objects that are + created in one code block persist in the R global environment and + can be re-used in a separate block. + + This is what Sweave does, and while I'm not saying we have to be + the same as Sweave, it wouldn't be hard for us to provide the same + behaviour in this case; if we don't, we risk undeservedly being + written off as an oddity by some. + + IOW one aspect of org-babel is that of a sort of functional + meta-programming language. This is crazy, in a very good + way. Nevertheless, wrt R I think there's going to be a lot of value + in providing for a working style in which the objects are stored in + the R session, rather than elisp/org buffer. This will be a very + familiar working style to lots of people. + + There are no doubt a number of different ways of accomplishing + this, the simplest being a hack like adding + +#+begin_src R +for(objname in ls()) + assign(objname, get(objname), envir=globalenv()) +#+end_src + +to the source code block function body. (Maybe wrap it in an on.exit() call). + +However this may deserve to be thought about more carefully, perhaps +with a view to having a uniform approach across languages. E.g. shell +code blocks have the same semantics at the moment (no persistence of +variables across code blocks), because the body is evaluated in a new +bash shell process rather than a running shell. And I guess the same +is true for python. However, in both these cases, you could imagine +implementing the alternative in which the body is evaluated in a +persistent interactive session. It's just that it's particularly +natural for R, seeing as both ESS and org-babel evaluate commands in a +single persistent R session. + +*** sessions [Eric] + +Thanks for bringing this up. I think you are absolutely correct that we +should provide support for a persistent environment (maybe called a +*session*) in which to evaluate code blocks. I think the current setup +demonstrates my personal bias for a functional style of programming +which is certainly not ideal in all contexts. + +While the R function you mention does look like an elegant solution, I +think we should choose an implementation that would be the same across +all source code types. Specifically I think we should allow the user to +specify an optional *session* as a header variable (when not present we +assume a default session for each language). The session name could be +used to name a comint buffer (like the *R* buffer) in which all +evaluation would take place (within which variables would retain their +values --at least once I remove some of the functional method wrappings +currently in place-- ). + +This would allow multiple environments to be used in the same buffer, +and once this setup was implemented we should be able to fairly easily +implement commands for jumping between source code blocks and the +related session buffers, as well as for dumping the last N commands from +a session into a new or existing source code block. + +Please let me know if you foresee any problems with this proposed setup, +or if you think any parts might be confusing for people coming from +Sweave. I'll hopefully find some time to work on this later in the +week. +*** implementation +in [[file:lisp/org-babel-comint.el][org-babel-comint.el]] + +Currently I've coppied and begun generalizing the functions for +interacting with R buffers. + ** TODO improve the source-block snippet [[file:~/src/emacs-starter-kit/src/snippets/text-mode/rst-mode/chap::name%20Chapter%20title][file:~/src/emacs-starter-kit/src/snippets/text-mode/rst-mode/chap::name Chapter title]] @@ -247,77 +325,6 @@ Another example is in the [[*operations%20in%20on%20tables][grades example]]. ** TODO pass mutliple reference arguments into R Can we do this? I wasn't sure how to supply multiple 'var' header args. Just delete this TODO if I'm being dense. -** TODO Create objects in top level (global) environment in R? - At the moment, objects created by computations performed in the - code block are evaluated in the scope of the - code-block-function-body and therefore disappear when the code - block is evaluated {unless you employ some extra trickery like - assign('name', object, env=globalenv()) }. I think it will be - desirable to also allow for a style wherein objects that are - created in one code block persist in the R global environment and - can be re-used in a separate block. - - This is what Sweave does, and while I'm not saying we have to be - the same as Sweave, it wouldn't be hard for us to provide the same - behaviour in this case; if we don't, we risk undeservedly being - written off as an oddity by some. - - IOW one aspect of org-babel is that of a sort of functional - meta-programming language. This is crazy, in a very good - way. Nevertheless, wrt R I think there's going to be a lot of value - in providing for a working style in which the objects are stored in - the R session, rather than elisp/org buffer. This will be a very - familiar working style to lots of people. - - There are no doubt a number of different ways of accomplishing - this, the simplest being a hack like adding - -#+begin_src R -for(objname in ls()) - assign(objname, get(objname), envir=globalenv()) -#+end_src - -to the source code block function body. (Maybe wrap it in an on.exit() call). - -However this may deserve to be thought about more carefully, perhaps -with a view to having a uniform approach across languages. E.g. shell -code blocks have the same semantics at the moment (no persistence of -variables across code blocks), because the body is evaluated in a new -bash shell process rather than a running shell. And I guess the same -is true for python. However, in both these cases, you could imagine -implementing the alternative in which the body is evaluated in a -persistent interactive session. It's just that it's particularly -natural for R, seeing as both ESS and org-babel evaluate commands in a -single persistent R session. - -*** sessions [Eric] - -Thanks for bringing this up. I think you are absolutely correct that we -should provide support for a persistent environment (maybe called a -*session*) in which to evaluate code blocks. I think the current setup -demonstrates my personal bias for a functional style of programming -which is certainly not ideal in all contexts. - -While the R function you mention does look like an elegant solution, I -think we should choose an implementation that would be the same across -all source code types. Specifically I think we should allow the user to -specify an optional *session* as a header variable (when not present we -assume a default session for each language). The session name could be -used to name a comint buffer (like the *R* buffer) in which all -evaluation would take place (within which variables would retain their -values --at least once I remove some of the functional method wrappings -currently in place-- ). - -This would allow multiple environments to be used in the same buffer, -and once this setup was implemented we should be able to fairly easily -implement commands for jumping between source code blocks and the -related session buffers, as well as for dumping the last N commands from -a session into a new or existing source code block. - -Please let me know if you foresee any problems with this proposed setup, -or if you think any parts might be confusing for people coming from -Sweave. I'll hopefully find some time to work on this later in the -week. ** PROPOSED support for passing paths to files between source blocks Maybe this should be it's own result type (in addition to scalars and From e8e24c024b069a02751f9a223ca5fc2cf3c4f204 Mon Sep 17 00:00:00 2001 From: Eric Schulte Date: Wed, 27 May 2009 19:01:29 -0700 Subject: [PATCH 6/6] added TODO fully purge org-babel-R of direct comint interaction --- org-babel.org | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/org-babel.org b/org-babel.org index 76f0f3ae3..8d39de4bd 100644 --- a/org-babel.org +++ b/org-babel.org @@ -114,7 +114,7 @@ table, allowing the test suite to be run be evaluation of the table and the results to be collected in the same table. -* Tasks [20/32] +* Tasks [20/33] ** TODO Create objects in top level (global) environment in R? *** initial requirement statement [DED] At the moment, objects created by computations performed in the @@ -192,6 +192,8 @@ in [[file:lisp/org-babel-comint.el][org-babel-comint.el]] Currently I've coppied and begun generalizing the functions for interacting with R buffers. +** TODO fully purge org-babel-R of direct comint interaction +try to remove all code under the [[file:lisp/org-babel-R.el::functions%20for%20evaluation%20of%20R%20code][;; functions for evaluation of R code]] line ** TODO improve the source-block snippet