config

Personal configuration.
git clone git://code.dwrz.net/config
Log | Files | Refs

ob-lisp.el (5325B)


      1 ;;; ob-lisp.el --- Babel Functions for Common Lisp   -*- lexical-binding: t; -*-
      2 
      3 ;; Copyright (C) 2009-2024 Free Software Foundation, Inc.
      4 
      5 ;; Authors: Joel Boehland
      6 ;;	 Eric Schulte
      7 ;;	 David T. O'Toole <dto@gnu.org>
      8 ;; Keywords: literate programming, reproducible research
      9 ;; URL: https://orgmode.org
     10 
     11 ;; This file is part of GNU Emacs.
     12 
     13 ;; GNU Emacs is free software: you can redistribute it and/or modify
     14 ;; it under the terms of the GNU General Public License as published by
     15 ;; the Free Software Foundation, either version 3 of the License, or
     16 ;; (at your option) any later version.
     17 
     18 ;; GNU Emacs is distributed in the hope that it will be useful,
     19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
     20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     21 ;; GNU General Public License for more details.
     22 
     23 ;; You should have received a copy of the GNU General Public License
     24 ;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
     25 
     26 ;;; Commentary:
     27 
     28 ;;; Support for evaluating Common Lisp code, relies on SLY or SLIME
     29 ;;; for all eval.
     30 
     31 ;;; Requirements:
     32 
     33 ;; Requires SLY (Sylvester the Cat's Common Lisp IDE) or SLIME
     34 ;; (Superior Lisp Interaction Mode for Emacs).  See:
     35 ;; - https://github.com/capitaomorte/sly
     36 ;; - https://common-lisp.net/project/slime/
     37 
     38 ;;; Code:
     39 
     40 (require 'org-macs)
     41 (org-assert-version)
     42 
     43 (require 'ob)
     44 (require 'org-macs)
     45 
     46 (declare-function sly-eval "ext:sly" (sexp &optional package))
     47 (declare-function slime-eval "ext:slime" (sexp &optional package))
     48 
     49 (defvar org-babel-tangle-lang-exts)
     50 (add-to-list 'org-babel-tangle-lang-exts '("lisp" . "lisp"))
     51 
     52 (defvar org-babel-default-header-args:lisp '())
     53 (defvar org-babel-header-args:lisp '((package . :any)))
     54 
     55 (defcustom org-babel-lisp-eval-fn #'slime-eval
     56   "The function to be called to evaluate code on the Lisp side.
     57 Valid values include `slime-eval' and `sly-eval'."
     58   :group 'org-babel
     59   :version "26.1"
     60   :package-version '(Org . "9.0")
     61   :type 'symbol)
     62 
     63 (defcustom org-babel-lisp-dir-fmt
     64   "(let ((*default-pathname-defaults* #P%S\n)) %%s\n)"
     65   "Format string used to wrap code bodies to set the current directory.
     66 For example a value of \"(progn ;; %s\\n   %%s)\" would ignore the
     67 current directory string."
     68   :group 'org-babel
     69   :version "24.1"
     70   :type 'string)
     71 
     72 (defun org-babel-expand-body:lisp (body params)
     73   "Expand BODY according to PARAMS, return the expanded body."
     74   (let* ((vars (org-babel--get-vars params))
     75 	 (result-params (cdr (assq :result-params params)))
     76 	 (print-level nil) (print-length nil)
     77          (prologue (cdr (assq :prologue params)))
     78          (epilogue (cdr (assq :epilogue params)))
     79 	 (body (if (null vars) (org-trim body)
     80 		 (concat "(let ("
     81 			 (mapconcat
     82 			  (lambda (var)
     83 			    (format "(%S (quote %S))" (car var) (cdr var)))
     84 			  vars "\n      ")
     85 			 ")\n"
     86                          (and prologue (concat prologue "\n"))
     87                          body
     88                          (and epilogue (concat "\n" epilogue "\n"))
     89                          ")"))))
     90     (if (or (member "code" result-params)
     91 	    (member "pp" result-params))
     92 	(format "(pprint %s)" body)
     93       body)))
     94 
     95 (defun org-babel-execute:lisp (body params)
     96   "Execute a block of Common Lisp code with Babel.
     97 BODY is the contents of the block, as a string.  PARAMS is
     98 a property list containing the parameters of the block."
     99   (let (eval-and-grab-output)
    100     (pcase org-babel-lisp-eval-fn
    101       (`slime-eval (org-require-package 'slime "SLIME")
    102                    (setq eval-and-grab-output 'swank:eval-and-grab-output))
    103       (`sly-eval (org-require-package 'sly "SLY")
    104                  (setq eval-and-grab-output 'slynk:eval-and-grab-output)))
    105     (org-babel-reassemble-table
    106      (let ((result
    107             (funcall (if (member "output" (cdr (assq :result-params params)))
    108                          #'car #'cadr)
    109                      (with-temp-buffer
    110                        (insert (org-babel-expand-body:lisp body params))
    111                        (funcall org-babel-lisp-eval-fn
    112                                 `(,eval-and-grab-output
    113                                   ,(let ((dir (if (assq :dir params)
    114                                                   (cdr (assq :dir params))
    115                                                 default-directory)))
    116                                      (format
    117                                       (if dir (format org-babel-lisp-dir-fmt dir)
    118                                         "(progn %s\n)")
    119                                       (buffer-substring-no-properties
    120                                        (point-min) (point-max)))))
    121                                 (cdr (assq :package params)))))))
    122        (org-babel-result-cond (cdr (assq :result-params params))
    123          (org-strip-quotes result)
    124          (condition-case nil
    125              (read (org-babel-lisp-vector-to-list result))
    126            (error result))))
    127      (org-babel-pick-name (cdr (assq :colname-names params))
    128 			  (cdr (assq :colnames params)))
    129      (org-babel-pick-name (cdr (assq :rowname-names params))
    130 			  (cdr (assq :rownames params))))))
    131 
    132 (defun org-babel-lisp-vector-to-list (results)
    133   "Convert #(...) values in RESULTS string into a (...) list."
    134   ;; TODO: better would be to replace #(...) with [...]
    135   (replace-regexp-in-string "#(" "(" results))
    136 
    137 (provide 'ob-lisp)
    138 
    139 ;;; ob-lisp.el ends here