From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp0 ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms11 with LMTPS id qEOwIuKgA19XDAAA0tVLHw (envelope-from ) for ; Mon, 06 Jul 2020 22:08:34 +0000 Received: from aspmx1.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp0 with LMTPS id CPqnHuKgA1+bcwAA1q6Kng (envelope-from ) for ; Mon, 06 Jul 2020 22:08:34 +0000 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id F16BA9408E8 for ; Mon, 6 Jul 2020 22:08:33 +0000 (UTC) Received: from localhost ([::1]:49104 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jsZHr-0007ge-5A for larch@yhetil.org; Mon, 06 Jul 2020 18:08:31 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:40764) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jsZHT-0007gW-Va for emacs-orgmode@gnu.org; Mon, 06 Jul 2020 18:08:07 -0400 Received: from mail-ej1-x644.google.com ([2a00:1450:4864:20::644]:44440) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jsZHR-00005B-QW; Mon, 06 Jul 2020 18:08:07 -0400 Received: by mail-ej1-x644.google.com with SMTP id ga4so44372804ejb.11; Mon, 06 Jul 2020 15:08:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:in-reply-to:references:date:message-id :mime-version; bh=X5gJihSOnmJwVuY32q+IfFtf5qOSVibWkg74JAYV60o=; b=YHolwXPLYmVFID2vwsFOOFBILSDWt2GQddZy8lms+OrAg0kv+4PMvR6frO/y83gr1c aH/tyHlAHi0UqOzLdRMw/qxZiJPFCeqg53hNvyoEIkKBdpp+ZYoUJFHQbmCpVYn7y3Lx +PoylbEeAMjbUYczhpGQcEpBfnAk14/7Oak4jTFnAnHeNO1v4zxhRzUajMFjULF7Rrcu LAMfBXiKzLIuswfzJ+vycv0VeatFFu3SpEviXWqSiSVffYj3Z9Braf1MohQM/FxkUVIg djAouADb1hhdNkvTN9Z9c02nSSFjZvkU2SyvUNdVBfxIwPbU675OaceUNf+SjfAe99le S9VA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:in-reply-to:references:date :message-id:mime-version; bh=X5gJihSOnmJwVuY32q+IfFtf5qOSVibWkg74JAYV60o=; b=ZiggNGLBX9n7FEnUOgJWl/MpldLW7IEh8gwf3tEyf80+a5iJCjmZdQS/LcmsOxoWf9 eZeD7+M88dwaSeEBTVrx8lPRiIdcgkJ8mjNl1dfphx2ffQZiT7MMoBduesiQV76jusLd SVYb5b4W8hN4elxRbddKmlWHdsX7tr8iy2sJfqDBy0uDWK8Y+KcVk6lGwXARTLE9o8yU NRisKA8/vIbmRP5kYAobfaIy+22tfk8K7OIOob0G5czM2+oQ3ihRaVOoRTRUXW0KSBvX cumxHi32la6GPIOomGJ4DyDOLXDDowPp/0wQOWFzKAlFQBQ+gfZlpeoW7zcpje/oUNWT 8DFA== X-Gm-Message-State: AOAM533lKn4vmCIWluzq15ogA/M4BS2mxFeVvaay0vtQk7YQhJDh7s9D C/wqp1M2T13FpB/igbn38DGuDTwg3mE= X-Google-Smtp-Source: ABdhPJzUQqlHDQx0Ql8tciKg8RCbfJwhRYmPK6CkYL2xJuoRiQHt2438jSKAyI01Y/cHQQu58++q9g== X-Received: by 2002:a17:907:2094:: with SMTP id pv20mr41560126ejb.512.1594073283545; Mon, 06 Jul 2020 15:08:03 -0700 (PDT) Received: from localhost (politkovskaja.torservers.net. [77.247.181.165]) by smtp.googlemail.com with ESMTPSA id o14sm17272846eja.121.2020.07.06.15.08.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Jul 2020 15:08:02 -0700 (PDT) From: akater To: Bastien Subject: Re: [PATCH] Add support for trace and error output streams in Common Lisp In-Reply-To: <874krtd69l.fsf@gnu.org> References: <87k12oyq0l.fsf@gmail.com> <874krtd69l.fsf@gnu.org> Date: Mon, 06 Jul 2020 21:58:32 +0000 Message-ID: <87wo3guwzb.fsf@gmail.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Received-SPF: pass client-ip=2a00:1450:4864:20::644; envelope-from=nuclearspace@gmail.com; helo=mail-ej1-x644.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: emacs-orgmode@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: emacs-orgmode@gnu.org Errors-To: emacs-orgmode-bounces+larch=yhetil.org@gnu.org Sender: "Emacs-orgmode" X-Scanner: scn0 Authentication-Results: aspmx1.migadu.com; dkim=pass header.d=gmail.com header.s=20161025 header.b=YHolwXPL; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (aspmx1.migadu.com: domain of emacs-orgmode-bounces@gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=emacs-orgmode-bounces@gnu.org X-Spam-Score: 0.19 X-TUID: 28qwdqa51z4J --=-=-= Content-Type: multipart/signed; boundary="==-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" --==-=-= Content-Type: text/plain Bastien writes: > Hi, > > akater writes: > >> This patch can't be merged right away: I need to sort out the exact >> SLIME version where the feature will be introduced. Some doc update is >> needed, too. > > did you finally managed to finalize this patch? > > If so, can you send it to the list as an attachment? > > We are in feature freeze, but small enhancement on ob- and ol- files > are acceptable if they don't break anything for the user. Sorry for the delay. The patch is now safe to apply. The feature is set to not activate until SLIME 2.28 which is likely months into the future. The reason for this is, I got a blessing from one of SLIME developers but they've not responded to my PR since; I also need to test with SLY. Delaying activation until SLIME 2.28 looks safe enough. There are some idiosyncrasies: I require elisp features cl-macs, cl-seq, subr-x in the middle of ob-lispe.el, right before they are needed. This is mostly due to state of the patch still being uncertain. I also define a variable for a newline emitted by Lisp because I'm always cautious of non-standard newlines on some platforms. This might be totally unnecessary. Note also that I update the documentation in addition to ob- files. This comes in a separate patch since the feature mentioned is not really available yet. --==-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIcBAEBCgAGBQJfA56QAAoJELK+sWGx7H9ECHMQAM/rlcelikqGNqIiqqkuJZyi m+YiaVEb6XrTiG4xF3Ov1ZcCDDV5K4hxqDMIvxFwKp520vtvZDiXHrrgsi7IaYa0 Utuv4pYNYW6SY1irA72XolGX2NO4W2nQQt0LX5iUGd75UBnGJhFez9ZWxegscrZW ALNVquxD+y7y7kF4sE833iOrFuZ0aFK8rXple6ZNybJxyTELhfDAZ7e4lNoZ8Bc3 agCWFlhbWecjeMQnEIIJw/aATmqO2zEQz7S6ket4FMxokqjNmmnGJ5GGOyK1OGiM ANab+8VHw+wRhkrBdTvhjbOmNZhr84zm4NxlxZTTKK2LfoIy6BvjMzXuRy8kagpk 83e+2snZFc929VXR+OlQ6dTh7fgAuyV777w0Y8BR68nbd6NDyanTTpJ1Q82zSQXZ uKnFH2bc9OYsmfZ9DFbOEjpWzdhCywZmC+pUTYrqTU9scyEgJsgE1UbAvUmPwevd qYRfrBWF2rvPQAun3AD08FfwZrk0kUHBifJ9GHE5mEmBuruHC8T+8oIc/DKu2m9S U82YxX2tc+uKAWalVEyYaESiMlIlgW7c96QWUl0r77JzVYOioCLn53YuW5Twn6BN qxtHXqRYFDbk+ZHpnQGF9I3JhxXwW0DLowgU7jXieTzTQsAvB9GqX96lOgoqewlv aAocstKAx1/rQFV0l7q0 =N23e -----END PGP SIGNATURE----- --==-=-=-- --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-ob-lisp.el-Add-support-for-trace-and-error-output-st.patch Content-Description: Main patch >From 93889d291d8b9539fb6b6950b98394c526cd96ed Mon Sep 17 00:00:00 2001 From: akater Date: Fri, 10 Apr 2020 02:52:21 +0000 Subject: [PATCH 1/2] ob-lisp.el: Add support for trace and error output streams * lisp/ob-lisp.el (org-babel-execute:lisp): Support recent more structured and featureful output from `swank:eval-and-grab-output'. * lisp/ob-core.el (org-babel-result-cond): Acknowledge new output options. * lisp/ob-clojure.el (ob-clojure-eval-with-slime): Support recent more structured and featureful output from `swank:eval-and-grab-output'. Trace and error outputs from Common Lisp are now available in org-babel evaluation with SLIME, starting with some future version of it. --- lisp/ob-clojure.el | 24 +++++++++++- lisp/ob-core.el | 2 + lisp/ob-lisp.el | 98 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 121 insertions(+), 3 deletions(-) diff --git a/lisp/ob-clojure.el b/lisp/ob-clojure.el index 299a326e4..da17ec948 100644 --- a/lisp/ob-clojure.el +++ b/lisp/ob-clojure.el @@ -213,7 +213,7 @@ (replace-regexp-in-string "nil" "" r)) result0))))))) -(defun ob-clojure-eval-with-slime (expanded params) +(defun ob-clojure-eval-with-slime--legacy (expanded params) "Evaluate EXPANDED code block with PARAMS using slime." (condition-case nil (require 'slime) (user-error "slime not available")) @@ -224,6 +224,28 @@ ,(buffer-substring-no-properties (point-min) (point-max))) (cdr (assq :package params))))) +(defun ob-clojure-eval-with-slime--multiple-targets-support (expanded params) + "Evaluate EXPANDED code block with PARAMS using slime." + (condition-case nil (require 'slime) + (user-error "slime not available")) + (with-temp-buffer + (insert expanded) + (let ((results-alist + (slime-eval + `(swank:eval-and-grab-output + ,(buffer-substring-no-properties (point-min) (point-max)) + '(common-lisp:*standard-output* common-lisp:values)) + (cdr (assq :package params))))) + (list + (cdr (assoc 'common-lisp:*standard-output* results-alist #'eq)) + (cdr (assoc 'common-lisp:values results-alist #'eq)))))) + +(defalias 'ob-clojure-eval-with-slime + (if (and (featurep 'slime) + (version< slime-version "2.25")) + 'ob-clojure-eval-with-slime--legacy + 'ob-clojure-eval-with-slime--multiple-targets-support)) + (defun org-babel-execute:clojure (body params) "Execute a block of Clojure code with Babel." (unless org-babel-clojure-backend diff --git a/lisp/ob-core.el b/lisp/ob-core.el index e798595bd..9ca3a81a8 100644 --- a/lisp/ob-core.el +++ b/lisp/ob-core.el @@ -3070,6 +3070,8 @@ Emacs shutdown.")) (member "pp" ,params) (member "file" ,params) (and (or (member "output" ,params) + (member "errors" ,params) + (member "trace" ,params) (member "raw" ,params) (member "org" ,params) (member "drawer" ,params)) diff --git a/lisp/ob-lisp.el b/lisp/ob-lisp.el index 8b126b26f..799144d2a 100644 --- a/lisp/ob-lisp.el +++ b/lisp/ob-lisp.el @@ -82,10 +82,14 @@ current directory string." (format "(pprint %s)" body) body))) -(defun org-babel-execute:lisp (body params) +(defun org-babel-execute:lisp--legacy (body params) "Execute a block of Common Lisp code with Babel. BODY is the contents of the block, as a string. PARAMS is -a property list containing the parameters of the block." +a property list containing the parameters of the block. + +This code is supposed to be superseded with the one in +`org-babel-execute:lisp--multiple-targets-support' +once the neccessary feature gets merged into SLIME." (require (pcase org-babel-lisp-eval-fn (`slime-eval 'slime) (`sly-eval 'sly))) @@ -116,6 +120,96 @@ a property list containing the parameters of the block." (org-babel-pick-name (cdr (assq :rowname-names params)) (cdr (assq :rownames params))))) +(defconst org-babel-lisp-output-options-to-slime-targets-table + ;; we can't reuse slime-output-targets here + ;; as this would make slime a requirement + ;; even for sly users + '(("output" . common-lisp:*standard-output*) + ("errors" . common-lisp:*error-output*) + ("trace" . common-lisp:*trace-output*)) + "Mapping from output-specifying header-args for Lisp code blocks +to output targets of Common Lisp function `swank:eval-and-grab-output'.") + +(defconst org-babel-lisp-output-options + (mapcar #'car org-babel-lisp-output-options-to-slime-targets-table) + "Keys from `org-babel-lisp-output-options-to-slime-targets-table'. +Must be kept in order of their appearance in that table.") + +(require 'cl-seq) +(eval-when-compile (require 'cl-macs)) + +(cl-defun org-babel-nsubstitute-multiple (alist cl-seq &key (test #'eql)) + "Like NSUBSTITUTE but applies all rules from ALIST." + (dolist (rule alist cl-seq) + (cl-nsubstitute (cdr rule) (car rule) cl-seq :test test))) + +(defconst org-babel-lisp-newline-string (make-string 1 10)) + +(eval-when-compile (require 'subr-x)) + +(defun org-babel-execute:lisp--multiple-targets-support (body params) + "Execute a block of Common Lisp code with Babel. +BODY is the contents of the block, as a string. PARAMS is +a property list containing the parameters of the block." + (require (pcase org-babel-lisp-eval-fn + (`slime-eval 'slime) + (`sly-eval 'sly))) + (org-babel-reassemble-table + (let* ((result-params (cdr (assq :result-params params))) + (output-targets + ;; arguably, it is more natural in org-mode + ;; to receive all outputs for :results output + ;; so that nothing gets sent to the repl buffer, + ;; and emit different outputs to different result blocks + ;; but for now we preserve compatibility with the old ways + (or + (org-babel-nsubstitute-multiple + org-babel-lisp-output-options-to-slime-targets-table + (cl-delete-duplicates + (cl-intersection result-params org-babel-lisp-output-options + :test #'string-equal) + :test #'string-equal) + :test #'string-equal) + (list 'common-lisp:values))) + (results-alist + (with-temp-buffer + (insert (org-babel-expand-body:lisp body params)) + (funcall org-babel-lisp-eval-fn + `(swank:eval-and-grab-output + ,(let ((dir (if (assq :dir params) + (cdr (assq :dir params)) + default-directory))) + (format + (if dir (format org-babel-lisp-dir-fmt dir) + "(progn %s\n)") + (buffer-substring-no-properties + (point-min) (point-max)))) + ',output-targets) + (cdr (assq :package params))))) + (result + (string-join + (cl-delete "" (org-babel-nsubstitute-multiple + results-alist output-targets :test #'eq) + :test #'string-equal) + org-babel-lisp-newline-string))) + (org-babel-result-cond result-params + (org-strip-quotes result) + (condition-case nil + (read (org-babel-lisp-vector-to-list result)) + (error result)))) + (org-babel-pick-name (cdr (assq :colname-names params)) + (cdr (assq :colnames params))) + (org-babel-pick-name (cdr (assq :rowname-names params)) + (cdr (assq :rownames params))))) + +(defalias 'org-babel-execute:lisp + (if (or (not (featurep 'slime)) + ;; relevant update to SLIME is in progress + ;; 2.28 is an estimation + (version< slime-version "2.28")) + 'org-babel-execute:lisp--legacy + 'org-babel-execute:lisp--multiple-targets-support)) + (defun org-babel-lisp-vector-to-list (results) ;; TODO: better would be to replace #(...) with [...] (replace-regexp-in-string "#(" "(" results)) -- 2.26.2 --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0002-Update-the-documentation.patch Content-Description: Documentation patch >From 0ed600fe7689beeb4c252d12754da8ca4d1e17d3 Mon Sep 17 00:00:00 2001 From: akater Date: Mon, 13 Apr 2020 12:42:49 +0000 Subject: [PATCH 2/2] Update the documentation --- doc/org-guide.org | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/org-guide.org b/doc/org-guide.org index 150762b13..dd31f0700 100644 --- a/doc/org-guide.org +++ b/doc/org-guide.org @@ -2489,7 +2489,8 @@ is the =results= header argument. It controls the /collection/, - Collection :: How the results should be collected from the code block. You may - choose either =output= or =value= (the default). + choose either =output= or =value= (the default). Some backends may + offer additional flavours of output, e.g. =errors=. - Type :: -- 2.26.2 --=-=-=--