{"action":"created","comment":{"url":"https://api.github.com/repos/nrepl/nrepl/pulls/comments/241772999","pull_request_review_id":185132921,"id":241772999,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDI0MTc3Mjk5OQ==","diff_hunk":"@@ -47,88 +47,65 @@\n     reader))\n \n (defn evaluate\n-  \"Evaluates some code within the dynamic context defined by a map of `bindings`,\n-   as per `clojure.core/get-thread-bindings`.\n+  \"Evaluates a msg's code within the dynamic context of its session.\n \n-   Uses `clojure.main/repl` to drive the evaluation of :code in a second\n-   map argument (either a string or a seq of forms to be evaluated), which may\n-   also optionally specify a :ns (resolved via `find-ns`).  The map MUST\n-   contain a Transport implementation in :transport; expression results and errors\n-   will be sent via that Transport.\n-\n-   Returns the dynamic scope that remains after evaluating all expressions\n-   in :code.\n-\n-   It is assumed that `bindings` already contains useful/appropriate entries\n-   for all vars indicated by `clojure.main/with-bindings`.\"\n-  [bindings {:keys [code ns transport session eval file line column] :as msg}]\n-  (let [explicit-ns-binding (when-let [ns (and ns (-> ns symbol find-ns))]\n-                              {#'*ns* ns})\n-        original-ns (bindings #'*ns*)\n-        maybe-restore-original-ns (fn [bindings]\n-                                    (if-not explicit-ns-binding\n-                                      bindings\n-                                      (assoc bindings #'*ns* original-ns)))\n-        file (or file (get bindings #'*file*))\n-        bindings (atom (merge bindings explicit-ns-binding {#'*file* file}))\n-        session (or session (atom nil))\n-        out (@bindings #'*out*)\n-        err (@bindings #'*err*)]\n-    (if (and ns (not explicit-ns-binding))\n+   Uses `clojure.main/repl` to drive the evaluation of :code (either a string\n+   or a seq of forms to be evaluated), which may also optionally specify a :ns\n+   (resolved via `find-ns`).  The map MUST contain a Transport implementation\n+   in :transport; expression results and errors will be sent via that Transport.\"\n+  [{:keys [code ns transport session eval file line column] :as msg}]\n+  (let [explicit-ns (and ns (-> ns symbol find-ns))\n+        original-ns (@session #'*ns*)\n+        maybe-restore-original-ns (if explicit-ns\n+                                    #(assoc % #'*ns* original-ns)\n+                                    identity)\n+        session (or session (atom {}))]\n+    (if (and ns (not explicit-ns))\n       (t/send transport (response-for msg {:status #{:error :namespace-not-found :done}\n                                            :ns ns}))\n-      (with-bindings @bindings\n-        (try\n-          (clojure.main/repl\n-           :eval (if eval (find-var (symbol eval)) clojure.core/eval)\n-           ;; clojure.main/repl paves over certain vars even if they're already thread-bound\n-           :init #(do (set! *compile-path* (@bindings #'*compile-path*))\n-                      (set! *1 (@bindings #'*1))\n-                      (set! *2 (@bindings #'*2))\n-                      (set! *3 (@bindings #'*3))\n-                      (set! *e (@bindings #'*e))\n-                      (when-some [v (resolve '*print-namespace-maps*)]\n-                        (var-set v (@bindings v))))\n-           :read (if (string? code)\n-                   (let [reader (source-logging-pushback-reader code line column)]\n-                     #(read {:read-cond :allow :eof %2} reader))\n-                   (let [code (.iterator ^Iterable code)]\n-                     #(or (and (.hasNext code) (.next code)) %2)))\n-           :prompt (fn [])\n-           :need-prompt (constantly false)\n-           ;; TODO: pretty-print?\n-           :print (fn [v]\n-                    (reset! bindings (assoc (capture-thread-bindings)\n-                                            #'*3 *2\n-                                            #'*2 *1\n-                                            #'*1 v))\n-                    (.flush ^Writer err)\n-                    (.flush ^Writer out)\n-                    (reset! session (maybe-restore-original-ns @bindings))\n-                    (t/send transport (response-for msg\n-                                                    {:value v\n-                                                     :ns (-> *ns* ns-name str)})))\n-           ;; TODO: customizable exception prints\n-           :caught (fn [e]\n-                     (let [root-ex (#'clojure.main/root-cause e)\n-                           previous-cause (.getCause e)]\n-                       ;; Check if the root cause or previous cause of the exception\n-                       ;; is a ThreadDeath exception. In case the exception is a\n-                       ;; CompilerException, the root cause is not returned by\n-                       ;; the root-cause function, so we check the previous cause\n-                       ;; instead.\n-                       (when-not (or (instance? ThreadDeath root-ex)\n-                                     (instance? ThreadDeath previous-cause))\n-                         (reset! bindings (assoc (capture-thread-bindings) #'*e e))\n-                         (reset! session (maybe-restore-original-ns @bindings))\n-                         (t/send transport (response-for msg {:status :eval-error\n-                                                              :ex (-> e class str)\n-                                                              :root-ex (-> root-ex class str)}))\n-                         (clojure.main/repl-caught e)))))\n-          (finally\n-            (.flush ^Writer out)\n-            (.flush ^Writer err)))))\n-    (maybe-restore-original-ns @bindings)))\n+      (try\n+        (clojure.main/repl\n+         :eval (if eval (find-var (symbol eval)) clojure.core/eval)\n+         ;; clojure.main/repl paves over certain vars even if they're already thread-bound\n+         :init #(let [bindings\n+                      (-> (get-thread-bindings)\n+                          (into @session)\n+                          (cond-> explicit-ns (assoc #'*ns* explicit-ns)\n+                                  file (assoc #'*file* file)))]\n+                  (pop-thread-bindings)\n+                  (push-thread-bindings bindings))\n+         :read (if (string? code)\n+                 (let [reader (source-logging-pushback-reader code line column)]\n+                   #(read {:read-cond :allow :eof %2} reader))\n+                 (let [code (.iterator ^Iterable code)]\n+                   #(or (and (.hasNext code) (.next code)) %2)))\n+         :prompt #(reset! session (maybe-restore-original-ns (capture-thread-bindings)))","path":"src/clojure/nrepl/middleware/interruptible_eval.clj","position":115,"original_position":115,"commit_id":"87e22dbbd9be3dbf80da8d554e69bb146f1aa93f","original_commit_id":"87e22dbbd9be3dbf80da8d554e69bb146f1aa93f","user":{"login":"bbatsov","id":103882,"node_id":"MDQ6VXNlcjEwMzg4Mg==","avatar_url":"https://avatars0.githubusercontent.com/u/103882?v=4","gravatar_id":"","url":"https://api.github.com/users/bbatsov","html_url":"https://github.com/bbatsov","followers_url":"https://api.github.com/users/bbatsov/followers","following_url":"https://api.github.com/users/bbatsov/following{/other_user}","gists_url":"https://api.github.com/users/bbatsov/gists{/gist_id}","starred_url":"https://api.github.com/users/bbatsov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bbatsov/subscriptions","organizations_url":"https://api.github.com/users/bbatsov/orgs","repos_url":"https://api.github.com/users/bbatsov/repos","events_url":"https://api.github.com/users/bbatsov/events{/privacy}","received_events_url":"https://api.github.com/users/bbatsov/received_events","type":"User","site_admin":false},"body":"That's called after init, right?","created_at":"2018-12-14T14:33:45Z","updated_at":"2018-12-14T14:33:45Z","html_url":"https://github.com/nrepl/nrepl/pull/101#discussion_r241772999","pull_request_url":"https://api.github.com/repos/nrepl/nrepl/pulls/101","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/nrepl/nrepl/pulls/comments/241772999"},"html":{"href":"https://github.com/nrepl/nrepl/pull/101#discussion_r241772999"},"pull_request":{"href":"https://api.github.com/repos/nrepl/nrepl/pulls/101"}}},"pull_request":{"url":"https://api.github.com/repos/nrepl/nrepl/pulls/101","id":238700145,"node_id":"MDExOlB1bGxSZXF1ZXN0MjM4NzAwMTQ1","html_url":"https://github.com/nrepl/nrepl/pull/101","diff_url":"https://github.com/nrepl/nrepl/pull/101.diff","patch_url":"https://github.com/nrepl/nrepl/pull/101.patch","issue_url":"https://api.github.com/repos/nrepl/nrepl/issues/101","number":101,"state":"open","locked":false,"title":"Rework bindings management (see #100)","user":{"login":"cgrand","id":47025,"node_id":"MDQ6VXNlcjQ3MDI1","avatar_url":"https://avatars0.githubusercontent.com/u/47025?v=4","gravatar_id":"","url":"https://api.github.com/users/cgrand","html_url":"https://github.com/cgrand","followers_url":"https://api.github.com/users/cgrand/followers","following_url":"https://api.github.com/users/cgrand/following{/other_user}","gists_url":"https://api.github.com/users/cgrand/gists{/gist_id}","starred_url":"https://api.github.com/users/cgrand/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cgrand/subscriptions","organizations_url":"https://api.github.com/users/cgrand/orgs","repos_url":"https://api.github.com/users/cgrand/repos","events_url":"https://api.github.com/users/cgrand/events{/privacy}","received_events_url":"https://api.github.com/users/cgrand/received_events","type":"User","site_admin":false},"body":"","created_at":"2018-12-14T12:02:12Z","updated_at":"2018-12-14T14:33:45Z","closed_at":null,"merged_at":null,"merge_commit_sha":"9f1c3e52001c42fe770290376b2c6fc8237ed024","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/nrepl/nrepl/pulls/101/commits","review_comments_url":"https://api.github.com/repos/nrepl/nrepl/pulls/101/comments","review_comment_url":"https://api.github.com/repos/nrepl/nrepl/pulls/comments{/number}","comments_url":"https://api.github.com/repos/nrepl/nrepl/issues/101/comments","statuses_url":"https://api.github.com/repos/nrepl/nrepl/statuses/87e22dbbd9be3dbf80da8d554e69bb146f1aa93f","head":{"label":"nrepl:bindings-cleanup","ref":"bindings-cleanup","sha":"87e22dbbd9be3dbf80da8d554e69bb146f1aa93f","user":{"login":"nrepl","id":39378471,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM5Mzc4NDcx","avatar_url":"https://avatars1.githubusercontent.com/u/39378471?v=4","gravatar_id":"","url":"https://api.github.com/users/nrepl","html_url":"https://github.com/nrepl","followers_url":"https://api.github.com/users/nrepl/followers","following_url":"https://api.github.com/users/nrepl/following{/other_user}","gists_url":"https://api.github.com/users/nrepl/gists{/gist_id}","starred_url":"https://api.github.com/users/nrepl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nrepl/subscriptions","organizations_url":"https://api.github.com/users/nrepl/orgs","repos_url":"https://api.github.com/users/nrepl/repos","events_url":"https://api.github.com/users/nrepl/events{/privacy}","received_events_url":"https://api.github.com/users/nrepl/received_events","type":"Organization","site_admin":false},"repo":{"id":928777,"node_id":"MDEwOlJlcG9zaXRvcnk5Mjg3Nzc=","name":"nrepl","full_name":"nrepl/nrepl","private":false,"owner":{"login":"nrepl","id":39378471,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM5Mzc4NDcx","avatar_url":"https://avatars1.githubusercontent.com/u/39378471?v=4","gravatar_id":"","url":"https://api.github.com/users/nrepl","html_url":"https://github.com/nrepl","followers_url":"https://api.github.com/users/nrepl/followers","following_url":"https://api.github.com/users/nrepl/following{/other_user}","gists_url":"https://api.github.com/users/nrepl/gists{/gist_id}","starred_url":"https://api.github.com/users/nrepl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nrepl/subscriptions","organizations_url":"https://api.github.com/users/nrepl/orgs","repos_url":"https://api.github.com/users/nrepl/repos","events_url":"https://api.github.com/users/nrepl/events{/privacy}","received_events_url":"https://api.github.com/users/nrepl/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/nrepl/nrepl","description":"A Clojure network REPL that provides a server and client, along with some common APIs of use to IDEs and other tools that may need to evaluate Clojure code in remote environments.","fork":false,"url":"https://api.github.com/repos/nrepl/nrepl","forks_url":"https://api.github.com/repos/nrepl/nrepl/forks","keys_url":"https://api.github.com/repos/nrepl/nrepl/keys{/key_id}","collaborators_url":"https://api.github.com/repos/nrepl/nrepl/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/nrepl/nrepl/teams","hooks_url":"https://api.github.com/repos/nrepl/nrepl/hooks","issue_events_url":"https://api.github.com/repos/nrepl/nrepl/issues/events{/number}","events_url":"https://api.github.com/repos/nrepl/nrepl/events","assignees_url":"https://api.github.com/repos/nrepl/nrepl/assignees{/user}","branches_url":"https://api.github.com/repos/nrepl/nrepl/branches{/branch}","tags_url":"https://api.github.com/repos/nrepl/nrepl/tags","blobs_url":"https://api.github.com/repos/nrepl/nrepl/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/nrepl/nrepl/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/nrepl/nrepl/git/refs{/sha}","trees_url":"https://api.github.com/repos/nrepl/nrepl/git/trees{/sha}","statuses_url":"https://api.github.com/repos/nrepl/nrepl/statuses/{sha}","languages_url":"https://api.github.com/repos/nrepl/nrepl/languages","stargazers_url":"https://api.github.com/repos/nrepl/nrepl/stargazers","contributors_url":"https://api.github.com/repos/nrepl/nrepl/contributors","subscribers_url":"https://api.github.com/repos/nrepl/nrepl/subscribers","subscription_url":"https://api.github.com/repos/nrepl/nrepl/subscription","commits_url":"https://api.github.com/repos/nrepl/nrepl/commits{/sha}","git_commits_url":"https://api.github.com/repos/nrepl/nrepl/git/commits{/sha}","comments_url":"https://api.github.com/repos/nrepl/nrepl/comments{/number}","issue_comment_url":"https://api.github.com/repos/nrepl/nrepl/issues/comments{/number}","contents_url":"https://api.github.com/repos/nrepl/nrepl/contents/{+path}","compare_url":"https://api.github.com/repos/nrepl/nrepl/compare/{base}...{head}","merges_url":"https://api.github.com/repos/nrepl/nrepl/merges","archive_url":"https://api.github.com/repos/nrepl/nrepl/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/nrepl/nrepl/downloads","issues_url":"https://api.github.com/repos/nrepl/nrepl/issues{/number}","pulls_url":"https://api.github.com/repos/nrepl/nrepl/pulls{/number}","milestones_url":"https://api.github.com/repos/nrepl/nrepl/milestones{/number}","notifications_url":"https://api.github.com/repos/nrepl/nrepl/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/nrepl/nrepl/labels{/name}","releases_url":"https://api.github.com/repos/nrepl/nrepl/releases{/id}","deployments_url":"https://api.github.com/repos/nrepl/nrepl/deployments","created_at":"2010-09-21T20:22:01Z","updated_at":"2018-12-14T11:14:40Z","pushed_at":"2018-12-14T12:06:41Z","git_url":"git://github.com/nrepl/nrepl.git","ssh_url":"git@github.com:nrepl/nrepl.git","clone_url":"https://github.com/nrepl/nrepl.git","svn_url":"https://github.com/nrepl/nrepl","homepage":"https://nrepl.xyz","size":1568,"stargazers_count":205,"watchers_count":205,"language":"Clojure","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":27,"mirror_url":null,"archived":false,"open_issues_count":27,"license":null,"forks":27,"open_issues":27,"watchers":205,"default_branch":"master"}},"base":{"label":"nrepl:master","ref":"master","sha":"79e2dfb7fa76b41c05e16a8ce4ef7395a4816487","user":{"login":"nrepl","id":39378471,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM5Mzc4NDcx","avatar_url":"https://avatars1.githubusercontent.com/u/39378471?v=4","gravatar_id":"","url":"https://api.github.com/users/nrepl","html_url":"https://github.com/nrepl","followers_url":"https://api.github.com/users/nrepl/followers","following_url":"https://api.github.com/users/nrepl/following{/other_user}","gists_url":"https://api.github.com/users/nrepl/gists{/gist_id}","starred_url":"https://api.github.com/users/nrepl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nrepl/subscriptions","organizations_url":"https://api.github.com/users/nrepl/orgs","repos_url":"https://api.github.com/users/nrepl/repos","events_url":"https://api.github.com/users/nrepl/events{/privacy}","received_events_url":"https://api.github.com/users/nrepl/received_events","type":"Organization","site_admin":false},"repo":{"id":928777,"node_id":"MDEwOlJlcG9zaXRvcnk5Mjg3Nzc=","name":"nrepl","full_name":"nrepl/nrepl","private":false,"owner":{"login":"nrepl","id":39378471,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM5Mzc4NDcx","avatar_url":"https://avatars1.githubusercontent.com/u/39378471?v=4","gravatar_id":"","url":"https://api.github.com/users/nrepl","html_url":"https://github.com/nrepl","followers_url":"https://api.github.com/users/nrepl/followers","following_url":"https://api.github.com/users/nrepl/following{/other_user}","gists_url":"https://api.github.com/users/nrepl/gists{/gist_id}","starred_url":"https://api.github.com/users/nrepl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nrepl/subscriptions","organizations_url":"https://api.github.com/users/nrepl/orgs","repos_url":"https://api.github.com/users/nrepl/repos","events_url":"https://api.github.com/users/nrepl/events{/privacy}","received_events_url":"https://api.github.com/users/nrepl/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/nrepl/nrepl","description":"A Clojure network REPL that provides a server and client, along with some common APIs of use to IDEs and other tools that may need to evaluate Clojure code in remote environments.","fork":false,"url":"https://api.github.com/repos/nrepl/nrepl","forks_url":"https://api.github.com/repos/nrepl/nrepl/forks","keys_url":"https://api.github.com/repos/nrepl/nrepl/keys{/key_id}","collaborators_url":"https://api.github.com/repos/nrepl/nrepl/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/nrepl/nrepl/teams","hooks_url":"https://api.github.com/repos/nrepl/nrepl/hooks","issue_events_url":"https://api.github.com/repos/nrepl/nrepl/issues/events{/number}","events_url":"https://api.github.com/repos/nrepl/nrepl/events","assignees_url":"https://api.github.com/repos/nrepl/nrepl/assignees{/user}","branches_url":"https://api.github.com/repos/nrepl/nrepl/branches{/branch}","tags_url":"https://api.github.com/repos/nrepl/nrepl/tags","blobs_url":"https://api.github.com/repos/nrepl/nrepl/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/nrepl/nrepl/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/nrepl/nrepl/git/refs{/sha}","trees_url":"https://api.github.com/repos/nrepl/nrepl/git/trees{/sha}","statuses_url":"https://api.github.com/repos/nrepl/nrepl/statuses/{sha}","languages_url":"https://api.github.com/repos/nrepl/nrepl/languages","stargazers_url":"https://api.github.com/repos/nrepl/nrepl/stargazers","contributors_url":"https://api.github.com/repos/nrepl/nrepl/contributors","subscribers_url":"https://api.github.com/repos/nrepl/nrepl/subscribers","subscription_url":"https://api.github.com/repos/nrepl/nrepl/subscription","commits_url":"https://api.github.com/repos/nrepl/nrepl/commits{/sha}","git_commits_url":"https://api.github.com/repos/nrepl/nrepl/git/commits{/sha}","comments_url":"https://api.github.com/repos/nrepl/nrepl/comments{/number}","issue_comment_url":"https://api.github.com/repos/nrepl/nrepl/issues/comments{/number}","contents_url":"https://api.github.com/repos/nrepl/nrepl/contents/{+path}","compare_url":"https://api.github.com/repos/nrepl/nrepl/compare/{base}...{head}","merges_url":"https://api.github.com/repos/nrepl/nrepl/merges","archive_url":"https://api.github.com/repos/nrepl/nrepl/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/nrepl/nrepl/downloads","issues_url":"https://api.github.com/repos/nrepl/nrepl/issues{/number}","pulls_url":"https://api.github.com/repos/nrepl/nrepl/pulls{/number}","milestones_url":"https://api.github.com/repos/nrepl/nrepl/milestones{/number}","notifications_url":"https://api.github.com/repos/nrepl/nrepl/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/nrepl/nrepl/labels{/name}","releases_url":"https://api.github.com/repos/nrepl/nrepl/releases{/id}","deployments_url":"https://api.github.com/repos/nrepl/nrepl/deployments","created_at":"2010-09-21T20:22:01Z","updated_at":"2018-12-14T11:14:40Z","pushed_at":"2018-12-14T12:06:41Z","git_url":"git://github.com/nrepl/nrepl.git","ssh_url":"git@github.com:nrepl/nrepl.git","clone_url":"https://github.com/nrepl/nrepl.git","svn_url":"https://github.com/nrepl/nrepl","homepage":"https://nrepl.xyz","size":1568,"stargazers_count":205,"watchers_count":205,"language":"Clojure","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":27,"mirror_url":null,"archived":false,"open_issues_count":27,"license":null,"forks":27,"open_issues":27,"watchers":205,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/nrepl/nrepl/pulls/101"},"html":{"href":"https://github.com/nrepl/nrepl/pull/101"},"issue":{"href":"https://api.github.com/repos/nrepl/nrepl/issues/101"},"comments":{"href":"https://api.github.com/repos/nrepl/nrepl/issues/101/comments"},"review_comments":{"href":"https://api.github.com/repos/nrepl/nrepl/pulls/101/comments"},"review_comment":{"href":"https://api.github.com/repos/nrepl/nrepl/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/nrepl/nrepl/pulls/101/commits"},"statuses":{"href":"https://api.github.com/repos/nrepl/nrepl/statuses/87e22dbbd9be3dbf80da8d554e69bb146f1aa93f"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"bbatsov"}}