From mboxrd@z Thu Jan 1 00:00:00 1970 From: Michael Gauland Subject: [PATCH] Use geiser for babel scheme evaluation. Date: Wed, 09 Jan 2013 12:46:49 +1300 Message-ID: <50ECAFE9.7060208@no8wireless.co.nz> References: <50E72B13.70709@no8wireless.co.nz> <87a9snlmhf.fsf@bzg.ath.cx> <87sj6ex0jj.fsf@bzg.ath.cx> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="------------enigBA64552B3BA55C7C81EF0298" Return-path: Received: from eggs.gnu.org ([208.118.235.92]:33789) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tsisr-0004xA-Na for emacs-orgmode@gnu.org; Tue, 08 Jan 2013 18:47:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Tsisp-0000J0-Ke for emacs-orgmode@gnu.org; Tue, 08 Jan 2013 18:47:05 -0500 Received: from jersey.rurallink.co.nz ([114.134.15.197]:55883 helo=smtp.rurallink.co.nz) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tsiso-0000IW-PZ for emacs-orgmode@gnu.org; Tue, 08 Jan 2013 18:47:03 -0500 In-Reply-To: <87sj6ex0jj.fsf@bzg.ath.cx> List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: Bastien Cc: emacs-orgmode@gnu.org This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enigBA64552B3BA55C7C81EF0298 Content-Type: multipart/mixed; boundary="------------060206020105040309000609" This is a multi-part message in MIME format. --------------060206020105040309000609 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable On 06/01/13 19:56, Bastien wrote: > Well, I'm afraid we'll have to go the clean way: just document the > deleted functions, the new ones, and the ones that have been > rewritten. No need to go too much into details. Also let's rename > `cleanse-org-babel-scheme-repl-map' to > `org-babel-scheme-cleanse-repl-map'. I've done the rename, un-dangled the parentheses, and prepared a changelo= g: Babel: Use geiser to manage scheme sessions * lisp/ob-scheme.el: Load the geiser library (run-scheme): Removed (org-babel-scheme-eoe): Removed (org-babel-scheme-cmd): Removed (scheme-program-name): Removed (org-babel-scheme-repl-map): Hash mapping session names to sessions. (org-babel-scheme-cleanse-repl-map): Remove dead sessions from map. (org-babel-scheme-get-session-buffer): Return buffer associated with a session. (org-babel-scheme-set-session-buffer): Record the buffer associated with a session. (org-babel-scheme-get-buffer-impl): Return the scheme implementation geiser associates with a buffer. (org-babel-scheme-get-repl): Switch to the scheme REPL buffer for a session, creating it if it doesn't exist. (org-bable-scheme-make-session-name): Generate a name for a session, if one was not specified. (org-babel-scheme-execute-with-geiser): Execute scheme code, creating the REPL if necessary. (org-babel-execute-scheme): Rewritten to use geiser. (org-babel-prep-session:scheme): Removed (org-babel-scheme-initiate-session): Removed This uses geiser to evaluate babel scheme source blocks, and generally improves scheme support. --------------060206020105040309000609 Content-Type: text/x-diff; name="0001-Use-geiser-for-babel-scheme-evaluation.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0001-Use-geiser-for-babel-scheme-evaluation.patch" =46rom bc33a46041086abd5d1fec321f104aa034823576 Mon Sep 17 00:00:00 2001 From: Michael Gauland Date: Wed, 9 Jan 2013 12:41:13 +1300 Subject: [PATCH] Use geiser for babel scheme evaluation. --- lisp/ob-scheme.el | 192 ++++++++++++++++++++++++++++++++---------------= ------ 1 files changed, 117 insertions(+), 75 deletions(-) diff --git a/lisp/ob-scheme.el b/lisp/ob-scheme.el index c9fa44a..31e0cad 100644 --- a/lisp/ob-scheme.el +++ b/lisp/ob-scheme.el @@ -2,7 +2,7 @@ =20 ;; Copyright (C) 2010-2013 Free Software Foundation, Inc. =20 -;; Author: Eric Schulte +;; Authors: Eric Schulte, Michael Gauland ;; Keywords: literate programming, reproducible research, scheme ;; Homepage: http://orgmode.org =20 @@ -33,27 +33,16 @@ ;; - a working scheme implementation ;; (e.g. guile http://www.gnu.org/software/guile/guile.html) ;; -;; - for session based evaluation cmuscheme.el is required which is -;; included in Emacs +;; - for session based evaluation geiser is required, which is available= from +;; ELPA. =20 ;;; Code: (require 'ob) -(eval-when-compile (require 'cl)) - -(declare-function run-scheme "ext:cmuscheme" (cmd)) +(load-library "geiser-impl") =20 (defvar org-babel-default-header-args:scheme '() "Default header arguments for scheme code blocks.") =20 -(defvar org-babel-scheme-eoe "org-babel-scheme-eoe" - "String to indicate that evaluation has completed.") - -(defcustom org-babel-scheme-cmd "guile" - "Name of command used to evaluate scheme blocks." - :group 'org-babel - :version "24.1" - :type 'string) - (defun org-babel-expand-body:scheme (body params) "Expand BODY according to PARAMS, return the expanded body." (let ((vars (mapcar #'cdr (org-babel-get-header params :var)))) @@ -65,70 +54,123 @@ ")\n" body ")") body))) =20 -(defvar scheme-program-name) + +(defvar org-babel-scheme-repl-map (make-hash-table :test 'equal) + "Map of scheme sessions to session names.") + +(defun org-babel-scheme-cleanse-repl-map () + "Remove dead buffers from the REPL map." + (maphash + (lambda (x y) + (when (not (buffer-name y)) + (remhash x org-babel-scheme-repl-map))) + org-babel-scheme-repl-map)) + +(defun org-babel-scheme-get-session-buffer (session-name) + "Look up the scheme buffer for a session; return nil if it doesn't exi= st." + (org-babel-scheme-cleanse-repl-map) ; Prune dead sessions + (gethash session-name org-babel-scheme-repl-map)) + +(defun org-babel-scheme-set-session-buffer (session-name buffer) + "Record the scheme buffer used for a given session." + (puthash session-name buffer org-babel-scheme-repl-map)) + +(defun org-babel-scheme-get-buffer-impl (buffer) + "Returns the scheme implementation geiser associates with the buffer."= + (with-current-buffer (set-buffer buffer) + geiser-impl--implementation)) + +(defun org-babel-scheme-get-repl (impl name) + "Switch to a scheme REPL, creating it if it doesn't exist:" + (let ((buffer (org-babel-scheme-get-session-buffer name))) + (or buffer=20 + (progn + (run-geiser impl) + (if name + (progn=20 + (rename-buffer name t) + (org-babel-scheme-set-session-buffer name (current-buffer)))) + (current-buffer))))) + +(defun org-babel-scheme-make-session-name (buffer name impl) + "Generate a name for the session buffer. + +For a named session, the buffer name will be the session name. + +If the session is unnamed (nil), generate a name. + +If the session is 'none', use nil for the session name, and +org-babel-scheme-execute-with-geiser will use a temporary session." + (let ((result=20 + (cond ((not name) + (concat buffer " " (symbol-name impl) " REPL")) + ((string=3D name "none") nil) + (name)))) + result)) + +(defun org-babel-scheme-execute-with-geiser (code output impl repl) + "Execute code in specified REPL. If the REPL doesn't exist, create it +using the given scheme implementation. + +Returns the output of executing the code if the output parameter +is true; otherwise returns the last value." + (let ((result nil)) + (with-temp-buffer + (insert (format ";; -*- geiser-scheme-implementation: %s -*-" impl= )) + (newline) + (insert (if output + (format "(with-output-to-string (lambda () %s))" code) + code)) + (geiser-mode) + (let ((repl-buffer (save-current-buffer (org-babel-scheme-get-repl= impl repl)))) + (when (not (eq impl (org-babel-scheme-get-buffer-impl (current-buffer))= )) + (message "Implementation mismatch: %s (%s) %s (s)" impl (symbolp impl= ) + (org-babel-scheme-get-buffer-impl (current-buffer)) + (symbolp (org-babel-scheme-get-buffer-impl (current-buffer))))) + (setq geiser-repl--repl repl-buffer) + (setq geiser-impl--implementation nil) + (geiser-eval-region (point-min) (point-max)) + (setq result + (if (equal (substring (current-message) 0 3) "=3D> ") + (replace-regexp-in-string "^=3D> " "" (current-message)) + "\"An error occurred.\"")) + (when (not repl) + (save-current-buffer (set-buffer repl-buffer) + (geiser-repl-exit)) + (set-process-query-on-exit-flag (get-buffer-process repl-buffer) nil)= + (kill-buffer repl-buffer)) + (setq result (if (or (string=3D result "#") + (string=3D result "#")) + nil + (read result))))) + result)) + (defun org-babel-execute:scheme (body params) "Execute a block of Scheme code with org-babel. This function is called by `org-babel-execute-src-block'" - (let* ((result-type (cdr (assoc :result-type params))) - (org-babel-scheme-cmd (or (cdr (assoc :scheme params)) - org-babel-scheme-cmd)) - (full-body (org-babel-expand-body:scheme body params))) - (read - (if (not (string=3D (cdr (assoc :session params)) "none")) - ;; session evaluation - (let ((session (org-babel-prep-session:scheme - (cdr (assoc :session params)) params))) - (org-babel-comint-with-output - (session (format "%S" org-babel-scheme-eoe) t body) - (mapc - (lambda (line) - (insert (org-babel-chomp line)) (comint-send-input nil t)) - (list body (format "%S" org-babel-scheme-eoe))))) - ;; external evaluation - (let ((script-file (org-babel-temp-file "scheme-script-"))) - (with-temp-file script-file - (insert - ;; return the value or the output - (if (string=3D result-type "value") - (format "(display %s)" full-body) - full-body))) - (org-babel-eval - (format "%s %s" org-babel-scheme-cmd - (org-babel-process-file-name script-file)) "")))))) - -(defun org-babel-prep-session:scheme (session params) - "Prepare SESSION according to the header arguments specified in PARAMS= =2E" - (let* ((session (org-babel-scheme-initiate-session session)) - (vars (mapcar #'cdr (org-babel-get-header params :var))) - (var-lines - (mapcar - (lambda (var) (format "%S" (print `(define ,(car var) ',(cdr var))))= ) - vars))) - (when session - (org-babel-comint-in-buffer session - (sit-for .5) (goto-char (point-max)) - (mapc (lambda (var) - (insert var) (comint-send-input nil t) - (org-babel-comint-wait-for-output session) - (sit-for .1) (goto-char (point-max))) var-lines))) - session)) - -(defun org-babel-scheme-initiate-session (&optional session) - "If there is not a current inferior-process-buffer in SESSION -then create. Return the initialized session." - (require 'cmuscheme) - (unless (string=3D session "none") - (let ((session-buffer (save-window-excursion - (run-scheme org-babel-scheme-cmd) - (rename-buffer session) - (current-buffer)))) - (if (org-babel-comint-buffer-livep session-buffer) - (progn (sit-for .25) session-buffer) - (sit-for .5) - (org-babel-scheme-initiate-session session))))) + (let* ((source-buffer (current-buffer)) + (source-buffer-name (replace-regexp-in-string ;; zap surrounding * + "^ ?\\*\\([^*]+\\)\\*" "\\1" (buffer-name source-buffer)))) + (save-excursion + (org-babel-reassemble-table + (let* ((result-type (cdr (assoc :result-type params))) + (impl (or (when (cdr (assoc :scheme params)) + (intern (cdr (assoc :scheme params)))) + geiser-default-implementation + (car geiser-active-implementations))) + (session (org-babel-scheme-make-session-name source-buffer-name (= cdr (assoc :session params)) impl)) + (full-body (org-babel-expand-body:scheme body params))) + (org-babel-scheme-execute-with-geiser full-body ; code + (string=3D result-type "output") ; output? + impl ; implementation + (and (not (string=3D session "none")) session)); session + ) + (org-babel-pick-name (cdr (assoc :colname-names params)) + (cdr (assoc :colnames params))) + (org-babel-pick-name (cdr (assoc :rowname-names params)) + (cdr (assoc :rownames params))))))) + =20 =20 (provide 'ob-scheme) =20 - - ;;; ob-scheme.el ends here --=20 1.7.2.5 --------------060206020105040309000609-- --------------enigBA64552B3BA55C7C81EF0298 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with undefined - http://www.enigmail.net/ iQIcBAEBAgAGBQJQ7K/uAAoJEKnkgIXLqylXSugQAILZvWUhmVkJKQb0fpOegUDo a3UfcBAPYBAD6MOlsLsTSdlH4LVygMXZiDzLKkvLmx99w6/BK8eNXgmQ4mPy6VMD 1yOYjqFyRUQAGHkRpGF+qhKo1nkHAsRT1g0BezAeiqcSyvHWR1WeWmuFuKNRsZeV GlslH2M+i5D3UebG4S+6ND7GCL0MJhArcsOhUTzAHXr2Uq7RXOzigWJtxzytbhAW rCKuGjZdSkRUIk3o29OppKIgrlBoyxCSmlU1ggiS+W8iF/RBOf8LadwqIytyjMgZ YQKRivs6lPMiGE8nrKWgNelvnUKsvFJCOsTPJNthI/EpeIrIElIMDN66v8W82vAU O4Er6uqyn0D86dAEETZdXbkA3d2HzSJSvhpnfxLabm4ApG5s36o4wdiIWgwBuqOE buOhm52acCvxKPGdUn9YtprnlPRQMg+NmU1hx3jJpZ88l7m8/U5iekFaouGwDhM3 73UuH2JoWaFbhTl2U+JZYuho9KgiqUZ5sgZ4LUNQuwKmKEWE01OwqiZugiTD4zWF GX7M87emCXM31YtXOZpi9YTWKd6MuZXO8aaJmBlIA7UXEaIo3KTI9PDPdGUFt8+t JAiQe6jfcPh0e2tSt4JLTVK2GZpL6It1jIEo4olsN2A3XFPI9GUAzwlj2N3foALm cC8seS/dkFA4DMncqJLP =u9Ap -----END PGP SIGNATURE----- --------------enigBA64552B3BA55C7C81EF0298--