After about 5 times test, And about 4 times review. I decide to PR. About new header argument :ns, I don't know how to write the test for it with loading CIDER in ERT. So have not write test. But I load my patch code, and run test on the following examples works fine.
#+begin_src clojure :results pp ;; (def greeting "hi there!") *ns* #+end_src #+RESULTS[<2018-04-13 20:37:16> f6f68aecdefcfd1be88fb144d47f5881f47b95db]: : #namespace[user] #+begin_src clojure :results pp (ns kk.test) (def he "hi") #+end_src #+RESULTS[<2018-04-13 20:37:24> 0b564a90ba588ba72b622a217834057600ac6d07]: : #'kk.test/he Deeper testing: #+begin_src emacs-lisp :results pp (nrepl-sync-request:eval "(clojure.pprint/pprint (do (ns user)\n (ns kk.test)\n (def he 2)))" (cider-current-connection) "user" ) #+end_src #+RESULTS[<2018-04-13 20:37:39> a05d9349d3b991a7fd47fb4ed268bf7e40f53e7a]: : (dict "status" : ("done" "state") : "id" "20" "out" "#'user/he\n" "session" "72ab6c95-08d4-4873-b83b-31c66aa26d62" "ns" "kk.test" "value" "nil" "changed-namespaces" : (dict) : "repl-type" "clj") #+begin_src clojure :results value :ns kk2 (def he "hi") *ns* #+end_src #+RESULTS[<2018-04-13 20:38:09> 89b32544ad50101e9f6f529a9e87a7bb86235cd9]: : nil#'kk2/he#namespace[kk2] What about another src block without ~:ns~ specified after previous specified src block? #+begin_src clojure :results value (def he "hi") *ns* #+end_src #+RESULTS[<2018-04-13 20:38:14> 85a2890ea59d198e2d1c771e2b80b1ae6335c416]: : nil#'user/he#namespace[user] More complex example: #+begin_src clojure :results output :var he="hi" :ns kk ;; (def he "hi") (prn he) (prn *ns*) #+end_src #+RESULTS[<2018-04-13 20:38:19> 9f6d74be8c54e2bc1b5047b569ddc6514c789cf0]: : "hi" : #namespace[kk]
From 1a0d80c000384b929b84a3755669e0d44c662558 Mon Sep 17 00:00:00 2001 From: stardiviner <numbch...@gmail.com> Date: Thu, 22 Mar 2018 01:21:22 +0800 Subject: [PATCH 1/6] * ob-clojure-literate.el: CIDER jack-in outside of project by default. --- contrib/lisp/ob-clojure-literate.el | 50 +++++++++++++++++------------ 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/contrib/lisp/ob-clojure-literate.el b/contrib/lisp/ob-clojure-literate.el index a7ab1894d..8d419b0b4 100644 --- a/contrib/lisp/ob-clojure-literate.el +++ b/contrib/lisp/ob-clojure-literate.el @@ -35,8 +35,10 @@ Don't auto jack in by default for not rude." :type 'boolean :group 'ob-clojure-literate) -(defcustom ob-clojure-literate-project-location (concat user-emacs-directory "Org-mode/") - "The location for `ob-clojure-literate' scaffold project." +(defcustom ob-clojure-literate-project-location nil + "The location for `ob-clojure-literate' scaffold project. +If it is nil, then `cider-jack-in' will jack-in outside of Clojure project. +If it is a directory, `ob-clojure-literate' will try to create Clojure project automatically." :type 'string :group 'ob-clojure-literate) @@ -45,7 +47,7 @@ Don't auto jack in by default for not rude." (defvar ob-clojure-literate-session-ns nil) (defvar ob-clojure-literate-cider-connections nil) -(defcustom ob-clojure-literate-default-session "*cider-repl ob-clojure*" +(defcustom ob-clojure-literate-default-session "*cider-repl localhost*" "The default session name for `ob-clojure-literate'." :type 'string :group 'ob-clojure-literate) @@ -104,23 +106,31 @@ Don't auto jack in by default for not rude." (defun ob-clojure-literate-auto-jackin () "Auto setup ob-clojure-literate scaffold and jack-in Clojure project." (interactive) - (unless (file-directory-p (expand-file-name ob-clojure-literate-project-location)) - (make-directory ob-clojure-literate-project-location t) - (let ((default-directory ob-clojure-literate-project-location)) - (shell-command "lein new ob-clojure"))) - (unless (or - (and (cider-connected-p) - (if (not (null ob-clojure-literate-session)) - (seq-contains cider-connections (get-buffer ob-clojure-literate-session)))) - cider-connections - (not (null ob-clojure-literate-session))) - ;; return back to original file. - (if (not (and (= (length (ob-clojure-literate-get-session-list)) 1) - (-contains-p (ob-clojure-literate-get-session-list) ob-clojure-literate-default-session))) - (save-window-excursion - (find-file (expand-file-name (concat ob-clojure-literate-project-location "ob-clojure/src/ob_clojure/core.clj"))) - (with-current-buffer "core.clj" - (cider-jack-in)))))) + (cond + ;; jack-in outside of Clojure project. + ((null ob-clojure-literate-project-location) + (if (member (get-buffer "*cider-repl localhost*") cider-connections) + (message "CIDER default session already launched.") + (cider-jack-in nil))) + ((not (null ob-clojure-literate-project-location)) + (unless (file-directory-p (expand-file-name ob-clojure-literate-project-location)) + (make-directory ob-clojure-literate-project-location t) + (let ((default-directory ob-clojure-literate-project-location)) + (shell-command "lein new ob-clojure"))) + (unless (or + (and (cider-connected-p) + (if (not (null ob-clojure-literate-session)) + (seq-contains cider-connections (get-buffer ob-clojure-literate-session)))) + cider-connections + (not (null ob-clojure-literate-session))) + ;; return back to original file. + (if (not (and (= (length (ob-clojure-literate-get-session-list)) 1) + (-contains-p (ob-clojure-literate-get-session-list) ob-clojure-literate-default-session))) + (save-window-excursion + (find-file (expand-file-name (concat ob-clojure-literate-project-location "ob-clojure/src/ob_clojure/core.clj"))) + (with-current-buffer "core.clj" + (cider-jack-in)))))) + )) (defun ob-clojure-literate-set-local-cider-connections (toggle?) "Set buffer local `cider-connections' for `ob-clojure-literate-mode' `TOGGLE?'." -- 2.17.0
From 5f14edb8ff3e8b1aaa14338753103c5bd961c014 Mon Sep 17 00:00:00 2001 From: stardiviner <numbch...@gmail.com> Date: Thu, 22 Mar 2018 01:43:18 +0800 Subject: [PATCH 2/6] * ob-clojure-literate.el: support use :ns header argument. - rename ob-clojure-literate-cider-do-not-find-ns to ob-clojure-literate-set-ns --- contrib/lisp/ob-clojure-literate.el | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/contrib/lisp/ob-clojure-literate.el b/contrib/lisp/ob-clojure-literate.el index 8d419b0b4..71ea909ba 100644 --- a/contrib/lisp/ob-clojure-literate.el +++ b/contrib/lisp/ob-clojure-literate.el @@ -151,14 +151,15 @@ If it is a directory, `ob-clojure-literate' will try to create Clojure project a ;; (setq-local cider-connections '()) )) -(defun ob-clojure-literate-cider-do-not-find-ns (body params) +(defun ob-clojure-literate-set-ns (body params) "Fix the issue that `cider-current-ns' try to invoke `clojure-find-ns' to extract ns from buffer." ;; TODO: Is it possible to find ns in `body'? (when (ob-clojure-literate-any-connection-p) (setq ob-clojure-literate-original-ns (cider-current-ns)) (with-current-buffer ob-clojure-literate-session (setq ob-clojure-literate-session-ns cider-buffer-ns)) - (setq-local cider-buffer-ns ob-clojure-literate-session-ns)) + (setq-local cider-buffer-ns (or (cdr (assq :ns params)) + ob-clojure-literate-session-ns))) (message (format "ob-clojure-literate: current CIDER ns is [%s]." cider-buffer-ns))) (defun ob-clojure-literate-set-local-session (toggle?) @@ -302,7 +303,7 @@ reset `RESULT' to `nil'." (equal major-mode 'org-mode)) ; `ob-clojure-literate-mode' only works in `org-mode'. (ob-clojure-literate-set-local-cider-connections ob-clojure-literate-mode) (ob-clojure-literate-set-local-session ob-clojure-literate-mode) - (advice-add 'org-babel-execute:clojure :before #'ob-clojure-literate-cider-do-not-find-ns) + (advice-add 'org-babel-execute:clojure :before #'ob-clojure-literate-set-ns) (advice-add 'org-babel-expand-body:clojure :filter-args #'ob-clojure-literate-inject-code) (advice-add 'org-babel-execute:clojure :filter-return #'ob-clojure-literate-support-graphics-result) (message "ob-clojure-literate minor mode enabled."))) @@ -310,7 +311,7 @@ reset `RESULT' to `nil'." ;;;###autoload (defun ob-clojure-literate-disable () "Disable Org-mode buffer locally for `ob-clojure-literate'." - (advice-remove 'org-babel-execute:clojure #'ob-clojure-literate-cider-do-not-find-ns) + (advice-remove 'org-babel-execute:clojure #'ob-clojure-literate-set-ns) (advice-remove 'org-babel-expand-body:clojure #'ob-clojure-literate-inject-code) (advice-remove 'org-babel-execute:clojure #'ob-clojure-literate-support-graphics-result) (setq-local cider-buffer-ns ob-clojure-literate-original-ns) -- 2.17.0
From 2676754c4f616d023efae75d7de7e0621a681616 Mon Sep 17 00:00:00 2001 From: stardiviner <numbch...@gmail.com> Date: Mon, 26 Mar 2018 09:47:54 +0800 Subject: [PATCH 3/6] * ob-clojure-literate.el: support vars initialization when prepare session. - org-babel-clojure-var-to-clojure --- contrib/lisp/ob-clojure-literate.el | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/contrib/lisp/ob-clojure-literate.el b/contrib/lisp/ob-clojure-literate.el index 71ea909ba..2d1d30db8 100644 --- a/contrib/lisp/ob-clojure-literate.el +++ b/contrib/lisp/ob-clojure-literate.el @@ -221,7 +221,14 @@ If it is a directory, `ob-clojure-literate' will try to create Clojure project a (defun org-babel-clojure-var-to-clojure (var) "Convert src block's `VAR' to Clojure variable." - ;; TODO: reference `org-babel-python-var-to-python' + (if (listp var) + (replace-regexp-in-string "(" "'(" var) + (cond + ((stringp var) + ;; wrap org-babel passed in header argument value with quote in Clojure. + (format "\"%s\"" var)) + (t + (format "%s" var)))) ) (defun org-babel-variable-assignments:clojure (params) @@ -230,8 +237,7 @@ If it is a directory, `ob-clojure-literate' will try to create Clojure project a (lambda (pair) (format "(def %s %s)" (car pair) - ;; (org-babel-clojure-var-to-clojure (cdr pair)) - (cdr pair))) + (org-babel-clojure-var-to-clojure (cdr pair)))) (org-babel--get-vars params))) ;;; Support header arguments :results graphics :file "image.png" by inject Clojure code. -- 2.17.0
From d59a789dd86359f3907163125389decf51d8da5d Mon Sep 17 00:00:00 2001 From: stardiviner <numbch...@gmail.com> Date: Mon, 26 Mar 2018 11:35:21 +0800 Subject: [PATCH 4/6] * ob-clojure.el (org-babel-execute:clojure) support :ns header argument. Remove optional parameter (cider-current-ns) to better handling namespace. --- lisp/ob-clojure.el | 54 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/lisp/ob-clojure.el b/lisp/ob-clojure.el index 890f60ada..35b4c3fe5 100644 --- a/lisp/ob-clojure.el +++ b/lisp/ob-clojure.el @@ -41,6 +41,7 @@ ;;; Code: (require 'cl-lib) (require 'ob) +(require 'subr-x) (declare-function cider-current-connection "ext:cider-client" (&optional type)) (declare-function cider-current-ns "ext:cider-client" ()) @@ -55,6 +56,7 @@ (declare-function slime-eval "ext:slime" (sexp &optional package)) (defvar nrepl-sync-request-timeout) +(defvar cider-buffer-ns) (defvar org-babel-tangle-lang-exts) (add-to-list 'org-babel-tangle-lang-exts '("clojure" . "clj")) @@ -80,19 +82,43 @@ If the value is nil, timeout is disabled." (const :tag "cider" cider) (const :tag "SLIME" slime))) +(defcustom org-babel-clojure-default-ns "user" + "Default Clojure namespace for src block when all find ns ways failed." + :type 'string + :group 'org-babel) + +(defun org-babel-clojure-cider-current-ns () + "Like `cider-current-ns' except `cider-find-ns'." + (or cider-buffer-ns + (when-let* ((repl-buf (cider-current-connection))) + (buffer-local-value 'cider-buffer-ns repl-buf)) + org-babel-clojure-default-ns)) + (defun org-babel-expand-body:clojure (body params) "Expand BODY according to PARAMS, return the expanded body." (let* ((vars (org-babel--get-vars params)) + (ns (cdr (assq :ns params))) + (ns-fallback (org-babel-clojure-cider-current-ns)) (result-params (cdr (assq :result-params params))) (print-level nil) (print-length nil) + (bind-vars (lambda (body) + (if (null vars) (org-trim body) + (concat + "(let [" + (mapconcat + (lambda (var) + (format "%S (quote %S)" (car var) (cdr var))) + vars "\n ") + "]\n" body ")")))) + (specify-namespace (lambda (body) + (concat + "(ns " (if (null ns) ns-fallback ns) ")\n" body))) (body (org-trim - (if (null vars) (org-trim body) - (concat "(let [" - (mapconcat - (lambda (var) - (format "%S (quote %S)" (car var) (cdr var))) - vars "\n ") - "]\n" body ")"))))) + (thread-last body + ;; variables binding + (funcall bind-vars) + ;; src block specified namespace :ns + (funcall specify-namespace))))) (if (or (member "code" result-params) (member "pp" result-params)) (format "(clojure.pprint/pprint (do %s))" body) @@ -102,9 +128,11 @@ If the value is nil, timeout is disabled." "Execute a block of Clojure code with Babel. The underlying process performed by the code block can be output using the :show-process parameter." - (let ((expanded (org-babel-expand-body:clojure body params)) - (response (list 'dict)) - result) + (let* ((expanded (org-babel-expand-body:clojure body params)) + (ns (cdr (assq :ns params))) + (ns-fallback (org-babel-clojure-cider-current-ns)) + (response (list 'dict)) + result) (cl-case org-babel-clojure-backend (cider (require 'cider) @@ -117,8 +145,7 @@ using the :show-process parameter." (let ((nrepl-sync-request-timeout org-babel-clojure-sync-nrepl-timeout)) (nrepl-sync-request:eval expanded - (cider-current-connection) - (cider-current-ns)))) + (cider-current-connection)))) (setq result (concat (nrepl-dict-get response @@ -152,8 +179,7 @@ using the :show-process parameter." (nrepl--merge response resp) ;; Update the status of the nREPL output session. (setq status (nrepl-dict-get response "status"))) - (cider-current-connection) - (cider-current-ns)) + (cider-current-connection)) ;; Wait until the nREPL code finished to be processed. (while (not (member "done" status)) -- 2.17.0
From 78948e652621f0e46ce52761aa6f372c5a919ece Mon Sep 17 00:00:00 2001 From: stardiviner <numbch...@gmail.com> Date: Mon, 2 Apr 2018 11:58:28 +0800 Subject: [PATCH 5/6] * ob-clojure-literate.el (ob-clojure-literate-get-session-list) get session from global connections list. --- contrib/lisp/ob-clojure-literate.el | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/contrib/lisp/ob-clojure-literate.el b/contrib/lisp/ob-clojure-literate.el index 2d1d30db8..0c928572b 100644 --- a/contrib/lisp/ob-clojure-literate.el +++ b/contrib/lisp/ob-clojure-literate.el @@ -63,7 +63,11 @@ If it is a directory, `ob-clojure-literate' will try to create Clojure project a (defun ob-clojure-literate-get-session-list () "Return a list of available started CIDER REPL sessions list." - (-map 'buffer-name cider-connections)) + (-map 'buffer-name + ;; for multiple connections case. + ;; get global value instead of buffer local. + (default-value 'cider-connections) + )) (defun ob-clojure-literate-set-session () "Set session name for buffer local." @@ -82,7 +86,7 @@ If it is a directory, `ob-clojure-literate' will try to create Clojure project a )) ;;;###autoload -(defun ob-clojure-literate-specify-session-header-argument () +(defun ob-clojure-literate-specify-session () "Specify ob-clojure header argument :session with value selected from a list of available sessions." (interactive) (let ((lang (nth 0 (org-babel-get-src-block-info)))) @@ -297,7 +301,7 @@ reset `RESULT' to `nil'." map) "Keymap for `ob-clojure-literate-mode'.") -(define-key org-babel-map (kbd "M-s") 'ob-clojure-literate-specify-session-header-argument) +(define-key org-babel-map (kbd "M-s") 'ob-clojure-literate-specify-session) (define-key org-babel-map (kbd "M-j") 'ob-clojure-literate-auto-jackin) ;; (define-key org-babel-map (kbd "M-e") 'cider-eval-last-sexp) ;; (define-key org-babel-map (kbd "M-d") 'cider-doc) -- 2.17.0
From 7eeecfe2e0009c99f197c2e4eedb68d92bb58e89 Mon Sep 17 00:00:00 2001 From: stardiviner <numbch...@gmail.com> Date: Mon, 2 Apr 2018 13:47:28 +0800 Subject: [PATCH 6/6] * ob-clojure-literate.el (ob-clojure-literate-inject-code) Handle no :file specified file is nil case. --- contrib/lisp/ob-clojure-literate.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/lisp/ob-clojure-literate.el b/contrib/lisp/ob-clojure-literate.el index 0c928572b..5dec2ad9b 100644 --- a/contrib/lisp/ob-clojure-literate.el +++ b/contrib/lisp/ob-clojure-literate.el @@ -265,7 +265,7 @@ Then you need to assign image variable to this :file value like: (directory (and dir (file-name-as-directory (expand-file-name dir)))) (result-type (cdr (assq :results params))) (file (cdr (assq :file params))) - (file-name (file-name-base file)) + (file-name (and file (file-name-base file))) ;; TODO: future support `:graphics-file' to avoid collision. (graphics-result (member "graphics" (cdr (assq :result-params params)))) ;; (graphics-file (cdr (assq :graphics-file params))) -- 2.17.0
-- [ stardiviner ] don't need to convince with trends. Blog: https://stardiviner.github.io/ IRC(freenode): stardiviner GPG: F09F650D7D674819892591401B5DF1C95AE89AC3
signature.asc
Description: PGP signature