Last active
December 14, 2024 07:00
-
-
Save timothypratley/100697670eacde2ad429fddb795fdcb9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns scicloj.kindly-render.nrepl.cursive-kindly-render-middleware | |
(:require [nrepl.middleware :as middleware] | |
[nrepl.transport :as t] | |
[nrepl.middleware.interruptible-eval :as eval] | |
[nrepl.middleware.print :as print]) | |
(:import (nrepl.transport Transport))) | |
(defn eval* | |
"Returns a wrapping map with metadata information" | |
[form] | |
(let [value (clojure.core/eval form)] | |
{:value value | |
:meta (meta value) | |
:print-meta (boolean *print-meta*) | |
:form-meta (meta form) | |
::print/keys #{:value :meta :print-meta :form-meta}})) | |
(defn unwrap-value | |
"Collapses the extra fields into msg" | |
[msg] | |
(if (and (contains? msg :value) | |
(map? (:value msg)) | |
(contains? (:value msg) ::print/keys)) | |
(merge msg (:value msg)) | |
msg)) | |
(defn unwrapping-transport [transport] | |
(reify Transport | |
(recv [this] (t/recv transport)) | |
(recv [this timeout] (t/recv transport timeout)) | |
(send [this msg] (t/send transport (unwrap-value msg))))) | |
(defn eval-with-meta | |
"A handler that adds metadata information into the msg result of eval ops" | |
[{:as req :keys [transport]}] | |
(assoc req | |
:eval `eval* | |
:transport (unwrapping-transport transport))) | |
;; the middleware | |
(defn wrap-with-meta | |
[handle] | |
(fn [msg] | |
(handle (eval-with-meta msg)))) | |
;; It's important that we wrap in the right place | |
;; The transport wrapping trick has to wrap transport before print/wrap-print | |
;; :eval needs to be added before interruptible-eval. | |
(middleware/set-descriptor! #'wrap-with-meta | |
{:requires #{#'print/wrap-print} | |
:expects #{#'eval/interruptible-eval} | |
:handles {}}) | |
;; Testing middleware mayhem | |
(comment | |
(require '[nrepl.server :as server]) | |
(def server (server/start-server :port 7888 | |
:handler (server/default-handler #'wrap-with-meta))) | |
(require '[nrepl.core :as nrepl]) | |
(with-open [conn (nrepl/connect :port 7888)] | |
(-> (nrepl/client conn 1000) | |
(nrepl/message {:op "eval" | |
:code "^{:kindly/kind :kind/map}{:hi 'there}"}) | |
(vec))) | |
(server/stop-server server)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment