Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support :init option when creating a repl #315

Closed
jaidetree opened this issue Mar 7, 2023 · 8 comments
Closed

Support :init option when creating a repl #315

jaidetree opened this issue Mar 7, 2023 · 8 comments

Comments

@jaidetree
Copy link
Contributor

Is your feature request related to a problem? Please describe.
When creating a repl with (nbb.repl/repl) it could take an :init option that evaluates forms to intern bindings within the repl.

Describe the solution you'd like
A similar implementation to core repl :init https://insideclojure.org/2020/02/11/custom-repl/ but in Slack you mentioned wrapping it in a promise for require support.

Describe alternatives you've considered
It might be possible to loop through the symbols of an existing namespace and create local defs to make a namespace available, but feels non-idiomatic, plus would likely not work with macros.

Additional context
Use case is I’m updating the nbb replit and thought it would be helpful if one could fire up the repl and instantly write something like:

(p/-> (js/fetch “https://google.com”) (.text) (println))

Questions

What would the usage look like? Based on what was discussed, I’m picturing:

(require ‘[promesa.core :as p])

(repl/repl
  {:init (p/do (apply require ‘[[promesa.core] :as p]
                                [clojure.repl :refer [doc]]
                                [cljs.pprint :refer [pp pprint]]))})
@borkdude
Copy link
Collaborator

borkdude commented Mar 7, 2023

:init would be a function, like in clojure.main/repl

@jaidetree
Copy link
Contributor Author

jaidetree commented Mar 7, 2023

Oh my mistake, that means it would be like this?

(require ‘[promesa.core :as p])

(repl/repl
  {:init #(apply require ‘[[promesa.core] :as p]
                           [clojure.repl :refer [doc]]
                           [cljs.pprint :refer [pp pprint]])})

Then the implementation should run that within a promise?

@borkdude
Copy link
Collaborator

borkdude commented Mar 7, 2023

the function can return a promise or an ordinary function and will then be chained onto the rest of the stuff here:

(.then (fn []

@jaidetree
Copy link
Contributor Author

That helps a lot! Last question: How should it deal with the optionality?

(-> ...
    (.then (if (ifn? (:init opts)) (:init opts) identity)))

@borkdude
Copy link
Collaborator

borkdude commented Mar 7, 2023

I'd say:

(let [init (:init opts identity)]
  (.then (...) init)

@jaidetree
Copy link
Contributor Author

Should that let also contain a runtime check like?

(when-not (ifn? init)
  (js/throw (js/Error. ":init must be a function")))

@borkdude
Copy link
Collaborator

borkdude commented Mar 7, 2023

I would say that's overkill

@borkdude
Copy link
Collaborator

@eccentric-j Maybe this would also be nice to have for the nREPL server? But I'll close the existing issue for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants