This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-04-07
Channels
- # babashka (31)
- # babashka-sci-dev (10)
- # beginners (64)
- # biff (11)
- # clerk (5)
- # cljdoc (2)
- # clojure (84)
- # clojure-boston (3)
- # clojure-conj (2)
- # clojure-europe (11)
- # data-science (19)
- # datomic (118)
- # fulcro (3)
- # graalvm (3)
- # hoplon (6)
- # inf-clojure (146)
- # instaparse (5)
- # lsp (13)
- # malli (3)
- # off-topic (13)
- # pedestal (5)
- # proletarian (5)
- # re-frame (14)
- # reitit (12)
- # releases (1)
- # ring (19)
- # scittle (2)
- # shadow-cljs (155)
- # slack-help (3)
Hey guys. I just installed inf-clojure and when I do inf-clojure-connect
and point it to my local REPL at localhost
/ 5555
, I get this:
Symbol's value as variable is void: inf-clojure-custom-repl-name
What's going on?that’s annoying. Can you debug it and see what’s going on?
You can m-x toggle-debug-on-error
and debug or get a stacktrace and see.
I’ve got to stash some local changes but i’ll pull it down and see what’s up
Let me see.
-UUU:----F1 *Org Src clojure ]* All L4 <N> (Clojure inf-cloj
1 Debugger entered--Lisp error: (void-variable inf-clojure-$
2 (or inf-clojure-custom-repl-name (if project-dir (forma$
3 (let* ((project-dir (clojure-project-dir)) (process-buf$
4 inf-clojure(("localhost" . 5555))
5 inf-clojure-connect("localhost" 5555)
6 funcall-interactively(inf-clojure-connect "localhost" 5$
7 call-interactively(inf-clojure-connect record nil)
8 command-execute(inf-clojure-connect record)
9 execute-extended-command(nil "inf-clojure-connect" "inf$
10 funcall-interactively(execute-extended-command nil "inf$
11 call-interactively(execute-extended-command nil nil)
12 command-execute(execute-extended-command)
I think I'll just need to get the stable version.
but we should raise an issue. someone recently committed some socket repl help and there were some changes so i guess this got left in
Anyway that defvar
doesn't do it totally, there are more issues: let: Symbol's value as variable is void: inf-clojure-socket-repl-type
I'll just report it as a bug and will use stable version.
OK that gets me to inf-clojure--prompt-repl-type
prompt (previously it failed after host
/`port`).
But ... I don't even expect this prompt.
Like the REPL is running, isn't that the point of connect?
the doc
and source
commands (and all of the others) depend on whether its a clojure, cljs, bb, planck, etc. repl
I see, clearly I don't understand the prompt. Let me go with clojure
and see...
OK so the REPL is running.
I can do C-x C-e
to eval. Strangely it doesn't show the result in the current buffer, I have to switch to the REPL buffer manually.
Am I too spoilt?
inf-clojure does not try to hide stuff from you. It’s meant to be a way to interact with a repl
OK, perfect, I'll do some learning on that. Just wanted to check it's behaving how it should.
I believe it was added in https://github.com/clojure-emacs/inf-clojure/pull/210/files
The other thing, if I want to connect from within Emacs to my custom REPL, I see there's inf-clojure-socket-repl
which makes me do that...except it doesn't allow me to connect to a custom REPL (`clojure -X:repl-server` from my deps.edn
).
Thank God for Emacs patching, I just added it to inf-clojure-socket-repl-startup-forms
:
(defvar inf-clojure-socket-repl-startup-forms
'((custom-repl-server . "clojure -X:repl-server :port %d")
...other opts)
But that's clearly not a long-term solution.
Is there a way to do this? All I want is that inf-clojure-socket-repl
offers me clojure -X:repl-server
.i think you should just start your repl in a terminal with all of your usual options
Fair enough.
trying to figure out how to pass this information to inf-clojure so it knows how to pass this information to the CLI is such a pain
and there’s so much documentation around the CLI that i think we should just use that
especially if your startup is so nice:
clj -X:repl-server :port 5000
and then inf-clojure-connect
I don’t mean to be overly negative. Making inf-clojure
work for everyone is great. I just see lots of downsides that you are immediately running into and no great general solutions
That's fine. For now I just want to learn how it works. I like Cider, but...no socket REPL, that's the thing.
Exactly 🙂 I'm not yet totally in the know, but I see the reasons and want to learn more!
i love it because i can easily connect to a jar running in CI over ssh, a prod jar locally, or my local dev setup. And my tooling remains the same across all instances
That's pretty cool.
java -D<socket-repl-stuff> -jar my-project.jar
clj -J-D<socket-repl-stuff> -A|-X|-M …
use ssh
to port forward and then connect to a jar running elsewhere, etc
Does the inf-clojure-custom-startup
actually work?
34 #+begin_src emacs-lisp :tangle .dir-locals.el
35 ((nil
36 ;; (inf-clojure-custom-startup . "clojure -X:repl-server")
37 (inf-clojure-custom-startup . ("localhost" . 5555))
38 (inf-clojure-custom-repl-type . clojure)))
39 #+end_src
I have this, load the vars, confirm them being safe, do inf-clojure
and it'd still ask me what do I want to connect to.
Neither of these two forms "clojure -X:repl-server"
or ("localhost" . 5555)
seem to work.M-x inf-clojure
inf-clojure-socket-repl
is also unaffected by the vars.
i can do
(setq inf-clojure-custom-startup "clojure -J-Dclojure.server.repl=\"{:port %d :accept clojure.core.server/repl}\" -A:grepl")
(setq inf-clojure-custom-repl-type 'clojure)
and then m-x inf-clojure-socket-repl
and it starts up with my custom startup and sets the typeThat's bloody weird!
@U11BV7MTK I evaluated these forms and it didn't work either.
(I mean the forms you just sent.)
Thanks, I'd be very grateful.
Thanks @U11BV7MTK! Let me try that now.
There are failing tests, but you've probably seen that.
I don't know what's going on. So I have the code from your PR.
Verified by ag inf-clojure-custom-repl-name $(find ~/.emacs.d -name inf-clojure.el) -A2
, it shows the code from the PR.
Quit Emacs. Start Emacs. Nothing interesting in *Messages*
.
Let's try if my vars are being read:
(message inf-clojure-custom-startup)
; "clojure -X:repl-server"
(message inf-clojure-custom-repl-type)
; "clojure"
All looks good to me. But then I do inf-clojure-socket-repl
and I get the interactive prompt Select Clojure socket REPL startup command
again.two things. The custom startup needs to have a "%d"
in it for where emacs gives it the port. It needs to assign the port to the startup so it knows what to connect to.
And then the custom repl type should be 'clojure
a symbol not a string
If I have 'clojure
I get this:
Debugger entered--Lisp error: (wrong-type-argument stringp clojure)
When I try to do (message inf-clojure-custom-repl-type)
.Ah fair enough.
(Totally not used to Elisp.)
I miss prn
.
Now I can't print the command since it has "%d"
in it and it expects an arg. But anyway I think I have the right value now.
... and I'm still getting that interactive prompt.
(message "clojure -X:repl-server :port %d")
Makes it fail
Because it expects argument for %d
.
(I just wanted to verify it had the right value.)
inf-clojure
is gonna call (format cmd port)
to check you can just do
(message (format "clojure -X:repl-server :port %d" 5000))
OK checked, the values are 100% right.
Yet it isn't working.
Same interactive prompt on both of inf-clojure
and inf-clojure-socket-repl
.
8 {:repl-server
9 {:exec-fn playground.repl/start-server
10 :exec-args {:name "repl-server"
11 :port 5555
12 :accept playground.repl/repl
13 :server-daemon false}}}
does everything work if you do
clj -X:repl-server :port 4567
and then inf-clojure-connect
to localhost
and 4567
?I can run it like that, yes, it starts on the right port.
And I can rlwrap nc localhost 4567
and it starts and responds.
Also responds. It did ask me REPL type, which it shouldn't, since I set the variable, but the REPL itself works, yes.
Happy to make it public, but I don't think there's anything interesting, because Emacs never even tries to start the command. The issue is before that.
File src/playground/repl.clj
(ns playground.repl
(:require [clojure.core.server :as s]))
(defn repl []
(clojure.main/repl
:init s/repl-init
:read s/repl-read
:print prn))
(defn start-server [{:keys [port] :as opts}]
(println (str "~ Starting socket REPL on port " port "."))
(println (str " Connect: rlwrap nc localhost " port))
(s/start-server opts))
And deps.edn
{:paths ["src"]
:aliases
{:repl-server
{:exec-fn playground.repl/start-server
:exec-args {:name "repl-server"
:port 5555
:accept playground.repl/repl
:server-daemon false}}}}
Really the wrapper doesn't do anything yet. It's my starting point for exploring socket REPLs that I want to play with once I get this working.
ah i know why. this feature expects to see a repl prompt to know when the repl is ready. and you never print a repl prompt
But are you sure? To me there's no indication it ever tries to start a process.
yes i’m sure. It has a process filter that waits for startup to complete so it knows the repl is ready. it could be delayed due to downloading dependencies, etc so it needs to know the repl is up and running
It goes to display the prompt straight away, there's no lag like if it'd be waiting.
I see.
It didn't occur to me it'd be necessary haha.
change it to this:
(defn start-server [{:keys [port] :as opts}]
(println (str "~ Starting socket REPL on port " port "."))
(println (str " Connect: rlwrap nc localhost " port))
(future (s/start-server opts))
(repl)
)
start-server
is a loop looking for connections so the repl never prints as the start-server
function never “finishes”. So give it its own thread and then start up a repl
note, it is waaaaaaay easier to let Clojure do this for you. Which is what that default connection string is doing:
"clojure -J-Dclojure.server.repl=\"{:port %d :accept clojure.core.server/repl}\""
that is gonna just start up the normal clojure
program (which defaults to a repl, and also starts the server on its own thread listening for socket connections.
What you are doing is saying “I’m the main entry point. and you should open up a socket and listen for connections” so it never starts the repl, and therefore emacs never knows it is readyOK thanks a lot Dan, I really appreciate your help 🙏:skin-tone-3:
It shows the right thing:
~ Starting socket REPL on port 4567.
Connect: rlwrap nc localhost 4567
user=>
But inf-clojure-socket-repl
still doesn't respond to that.
I want to try with the default clojure command you pasted first and see.and this is why that system property way to start a socket repl is so nice: -J-Dclojure.server.repl
you can have other entry points. Want reveal to startup and give you that nice interaction? clj -J-D… -M reveal
. Have a -X
startup? You can start the socket repl and have the entry point you want
I assume you start with inf-clojure-socket-repl
, correct?
OK so something else must be going on still.
Even with (inf-clojure-custom-startup . "clojure -J-Dclojure.server.repl=\"{:port %d :accept clojure.core.server/repl}\" -A:grepl")
property it still doesn't work.
i just restarted emacs, evaled
(setq inf-clojure-custom-startup "clojure -X:repl-server :port %d")
(setq inf-clojure-custom-repl-type 'clojure)
and then inf-clojure-socket-repl
ag inf-clojure-custom-repl-name $(find ~/.emacs.d -name inf-clojure.el) -A2
521:(defvar inf-clojure-custom-repl-name nil
522- "A string to be used as the repl buffer name.")
523-
--
831: inf-clojure-custom-repl-name
832- (if project-dir
833- (format "inf-clojure %s" (inf-clojure--project-name project-dir))
Right, that's the new code.
(created-repl-buffer (inf-clojure-connect host port :suppress-message)))
Yeah me too. It looks like a very straightforward thing.
"clojure -J-Dclojure.server.repl=\"{:port %d :accept clojure.core.server/repl}\" -A:grepl"
OK...so I find something out:
I use Org-mode for everything. Great for dumb people with loosy memory, I have code and notes together. (Also allows for grouping things logically and other things, which I really appreciate.)
I normally edit code in a Orgmode narrow (`C-C '`). That gives me all that's in the current source block as a new buffer. I edit it, run CLJ stuff there and then when I'm happy, I close it by C-c '
and it saves the update into the main buffer.
If I open the actual tangled CLJ source file, it works there.
In the Orgmode narrow buffer, it doesn't.
* Deps
Ref [[ and CLI guide: socket REPL]].
#+begin_src clojure :tangle deps.edn
{:paths ["src"]
:aliases
{:repl-server
{:exec-fn playground.repl/start-server
:exec-args {:name "repl-server"
:port 5555
:accept playground.repl/repl
:server-daemon false}}}} ; How to run as a daemon?
#+end_src
Ref [[.
#+begin_src emacs-lisp
(setq inf-clojure-custom-startup "clojure -X:repl-server :port %d")
(setq inf-clojure-custom-repl-type 'clojure)
(message (format inf-clojure-custom-startup 5000))
(message (symbol-name inf-clojure-custom-repl-type))
#+end_src
Eval this, then ~inf-clojure-socket-repl~.
Ref [[.
#+begin_src emacs-lisp :tangle .dir-locals.el
((nil
;(inf-clojure-custom-startup . "clojure -X:repl-server :port %d")
(inf-clojure-custom-startup . "clojure -J-Dclojure.server.repl=\"{:port %d :accept clojure.core.server/repl}\" -A:grepl")
;(inf-clojure-custom-startup . ("localhost" . 5555))
(inf-clojure-custom-repl-type . clojure)
;; (inf-clojure-prompt-read-only t)
;; (inf-clojure-repl-use-same-window t)
))
#+end_src
#+begin_src clojure :tangle src/playground/repl.clj :mkdirp yes
(ns playground.repl
(:require [clojure.core.server :as s]))
(defn repl []
(clojure.main/repl
:init s/repl-init
:read s/repl-read
:print prn))
(defn start-server [{:keys [port] :as opts}]
(println (str "~ Starting socket REPL on port " port "."))
(println (str " Connect: rlwrap nc localhost " port))
(future (s/start-server opts))
(repl))
#+end_src
** Usage
#+begin_src sh
clojure -X:repl-server
clojure -X:repl-server :port 51234
rlwrap nc localhost 5555
#+end_src
#+begin_src clojure :tangle src/playground.clj :mkdirp yes
(filter odd?)
(range 10)
(range)
#+end_src
1. If I go to the last code block that tangles into src/playground.clj
, open it via C-c '
and try to connect to the REPL there using inf-clojure-socket-repl
, no luck.
2. Same thing works fine if I open src/playground.clj
manually as its own buffer.
So this is related to that setup. Normally other CLJ tools work in that narrow Orgmode buffer, including Clojure mode, Lispy and Cider as well.
No don't worry about it, I'll have a look.
Just filling you in.
yeah. step through the code. You’ll need to debug it to see where it goes off the rails
Project root could be a culprit
OK, at least I'll learn some Emacs debugging.
The workaround is to first open a .clj
file, inf-clojure-socket-repl
, then close the source file and go back to the normal Org mode literary programming workflow.
Will debug it at some point, but this works for now and I'm more interested in socket REPLs than in Emacs, so I'll leave it at that for the time being.