Fork me on GitHub
#cider
<
2018-02-21
>
wusticality00:02:36

took a clojure gig, trying to use cider, i’m an experienced emacs user

wusticality00:02:23

i can’t for the life of me get cider-find-var to work, just says Symbol 'blah/foo' not resolved no matter what I do, I’m surprised since cider should have access to the jvm and language object model

wusticality00:02:44

I’m jacked into a lein project too and have the nREPL running

wusticality00:02:54

any leads? any help would be greatly appreciated

wusticality00:02:13

also curious if methods like cider-find-ns work for *.cljs

tanzoniteblack00:02:34

@iwannaseethelight 1.) did you compile the code you're trying to resolve a symbol in? 2.) If you did, how did you start the nrepl, and is there a warning at the top of the repl buffer

wusticality00:02:11

hey @tanzoniteblack, I just navigated to my lein project, booted up emacs, and executed M-x cider-jack-in

wusticality00:02:26

it’s running properly it seems (it’s a web server)

tanzoniteblack00:02:09

so that's a yes on the first one then? That you've run cider-load-buffer or something similar to load the code in the running repl environment?

wusticality00:02:31

it seems that M-x cider-jack-in loads the lein project, no?

wusticality00:02:37

i haven’t explicitly loaded any code

wusticality00:02:49

but i can go to the cider repl and execute functions

wusticality00:02:57

that are in the project, it’s clearly running

arrdem01:02:55

@iwannaseethelight I don’t think that cider-find-var can discover code you haven’t loaded.

arrdem01:02:09

Eg. it doesn’t implicitly try to require the namespace.

arrdem01:02:29

so if (the-ns 'your-missing-namespace) doesn’t work in the REPL CIDER won’t be able to find it either.

wusticality01:02:17

so cider doesn’t load all clojure code in your project?

arrdem01:02:21

No it doesn’t.

wusticality01:02:37

doesn’t that .. sort of make cider-find-var totally pointless 😛

arrdem01:02:02

No it doesn’t. cider-find-var works great once you’ve loaded your code and are deving.

wusticality01:02:05

basically i’m trying to replicate jump to function / symbol

wusticality01:02:31

there are about 500 clojure scripts in this big project

wusticality01:02:50

i was under the impression that cider was talking to the jvm over nREPL

arrdem01:02:07

Yeah, but if your code isn’t loaded the JVM doesn’t know about it either.

arrdem01:02:27

CIDER isn’t doing any classpath search or anything to try and find namespaces.

arrdem01:02:34

You could build that if you wanted to but I’d be surprised if it was in the box.

arrdem01:02:05

Remember, CIDER is a feature layer for REPLs with the expectation that your code is loaded into Clojure all the time.

wusticality01:02:36

i’m clearly missing something

wusticality01:02:46

i’m coming from c++ land at any rate

arrdem01:02:08

Okay! No worries, welcome to Clojure!

wusticality01:02:14

I guess I thought that when you jack in, it starts up the jvm, loads your project, and communicates with it over the repl

wusticality01:02:31

i thought that find var would just ask the jvm about a symbol / function and return a result to you

arrdem01:02:34

well… the JVM only loads the code it needs for the REPL.

arrdem01:02:19

So think about it this way. When you “boot a REPL” you’re telling the JVM “here’s my main(), go run that”. In this case, your main is the nREPL entry point, so it loads nREPL and Clojure and anything else required to stand the server up.

arrdem01:02:54

The JVM only loads code when it needs to, so until you go explicitly (require 'your-ns) or something else Clojure, nREPL and the JVM are completely oblivious to the fact that it’s valid code.

arrdem01:02:38

So if you open up one of your scripts and C-c C-k to compile and load the namespace, then it’ll be loaded into your nREPL connection and you’ll be able to explore it with cider-find-var and cider-find-ns.

wusticality01:02:45

question on that - does loading a namespace also load dependencies?

wusticality01:02:52

thereby allowing you to jump to shit

wusticality01:02:05

so you have to load a file, jump to var, load that file, jump to another thing ..

wusticality01:02:14

i wonder if there’s a way to improve that workflow

arrdem01:02:27

No. You load one file, and that causes all of its transitive dependencies to become loaded, and then you can go wherever.

wusticality01:02:17

i guess I could defadvice around cider-find-var to load the file first

wusticality01:02:19

sort of gross

arrdem01:02:35

Yep. You could also use your user.clj file to require your entry point ns.

wusticality01:02:39

actually wait

arrdem01:02:40

That’s a common trick.

wusticality01:02:08

i’m assuming dependencies are loaded recursively

arrdem01:02:12

Yep they are.

wusticality01:02:27

so if i load file a, and it imports namespace b, which imports c, c is implicitly loaded when a is

wusticality01:02:34

so i should be able to jump to shit in c

wusticality01:02:46

that user.clj - is that a project-level thing? apologies, new to clojure dev

arrdem01:02:59

clojure.core/*loaded-libs* is a collection of all the namespaces that Clojure thinks it has loaded.

arrdem01:02:47

user.clj is a magical file that clojure.lang.RT loads before it goes and does whatever you asked it to such as booting nREPL. Typically people will put it in a dev directory and use it for development utilities.

wusticality01:02:27

oh on that note haha - i notice that cider seems to create a user ns, which sucks because this huge project declares a user ns so none of the autocomplete works for user unless it’s fully qualified ..

wusticality01:02:54

jesus, I just discovered M-,, i’ve been a hardcore emacs user for 10+ years, how have I not know about that command

wusticality01:02:07

cider-pop-back

arrdem01:02:19

Clojure creates the user namespace actually.

arrdem01:02:31

It’s the magical default namespace you get when you start a REPL.

wusticality01:02:35

i wonder if there’s a way to prevent that, it’s causing problems unfortunately

wusticality01:02:44

probably a setting i’m guessing

arrdem01:02:55

What are you trying to do?

arrdem01:02:10

You shouldn’t need to do anything like that.

wusticality01:02:30

well i have no problems with a user ns but unfortunately they declare things like a.b.c.user, and if you type user/.. nothing happens unless you fully qualify user

wusticality01:02:11

in other words, if i’m in like thebigproject.main, and it imports a.b.c.user :as user, and you then type user/.. at the repl or in code, nothing happens

wusticality01:02:21

cause it thinks you’re referring to the user ns

arrdem01:02:30

Are you in thebigproject.main?

arrdem01:02:42

Is it loaded? C-c C-k

wusticality01:02:49

so in that file, they import a.b.c.user :as user

wusticality01:02:19

yep it’s loaded, everything else works except for user/

arrdem01:02:20

Being “in” that namespace != it being loaded FWIW. You can C-c M-n to namespaces that aren’t loaded yet.

wusticality01:02:31

well it’s the main ns that gets loaded when the project is booted via jack in

wusticality01:02:39

the repl prompt says thebigproject.main

wusticality01:02:46

i mean, it clearly seems to be loaded no?

arrdem01:02:44

🤷 recompiling a namespace is super cheap I usually just C-c C-k all the time just to be sure.

wusticality01:02:57

interestingly, some others don’t appear to work

wusticality01:02:08

they have one that’s like [a.b.c :as c]

wusticality01:02:11

c/ doesn’t work

wusticality01:02:15

but others next to it do with longer names

arrdem01:02:27

Yeah that probably means that you’re “in” the namespace, but the namespace hasn’t been loaded so it’s empty.

wusticality01:02:42

can you restate that?

wusticality01:02:48

didn’t quite parse 🙂

wusticality01:02:34

btw, that :as c thing up there

wusticality01:02:41

if i type a.b.c/ it works fine

wusticality01:02:48

but it doesn’t if it’s just c/

arrdem01:02:56

No worries. Being “in” a namespace means that clojure.core/*ns* points to the namespace named thebigproject.main. Changing current namespace to thebigproject.main via (in-ns 'thebigproject.main) will create that namespace and set *ns* appropriately, but it won’t load any code in the file that corresponds to thebigproject.main.

arrdem01:02:27

This means that you’re “in” the namespace, but the (ns) form that defines all your (:require ... :as ...) hasn’t been executed

arrdem01:02:34

so those aliases don’t exist yet.

wusticality01:02:37

would i do like

wusticality01:02:45

why do some aliases work then?

arrdem01:02:47

C-c C-k man that’s why I keep saying it.

arrdem01:02:03

Because they aren’t the aliases they’re the fully qualified names I think based on what you’re saying.

wusticality01:02:24

yeah just tried that, no change

wusticality01:02:32

for c/ or user/ - everything else works

wusticality01:02:00

in other words, i have other aliases like a.b.x.stuff foobar and foobar/ works

wusticality01:02:10

thanks for your time btw 😉

arrdem01:02:13

well for c/ that’s too little text for company’s autocomplete popover to activate.

arrdem01:02:24

I bet if you tab in the REPL it works just fine

wusticality01:02:26

that’s just funny

arrdem01:02:33

I’m not even kidding >.>

wusticality01:02:38

hah, you’re right.

wusticality01:02:41

not sure about user/

arrdem01:02:48

yeah that may just be blacklisted no ideas there.

wusticality01:02:50

nothing happens with user

wusticality01:02:57

kinda sucks, they use it all over the place unfortunately

arrdem01:02:04

does user/<tab> work in the REPL?

wusticality01:02:19

nothing happens for that

arrdem01:02:21

that’s really weird

wusticality01:02:22

interestingly, if i do like

arrdem01:02:39

does com.your.crappy.code.user/<tab> work?

wusticality01:02:28

yep, fully qualifying works

wusticality01:02:31

btw, just did this

wusticality01:02:43

switched to user ns in repl, defined two functions, switched back

wusticality01:02:53

then user/ shows those two functions as completions

wusticality01:02:00

i wonder if there’s a way to change the name of that generated ns

wusticality01:02:10

maybe it can be deleted? 😛

wusticality01:02:17

that’s really hacky though

arrdem01:02:21

deleting namespaces isn’t possible

wusticality01:02:41

you’d think that it’d use the most derived (aka, the alias in the ns i’m in)

arrdem01:02:07

one sec I need to look up some namespace incantations

wusticality01:02:26

btw, do you usually do (in-ns 'thing) at the repl to switch?

arrdem01:02:51

I usually just C-c C-k C-c M-n from the file for that namespace.

wusticality01:02:20

2 other questions btw

wusticality01:02:28

is there a separate repl for cljs?

arrdem01:02:28

@iwannaseethelight (ns-aliases *ns*) what does that print?

arrdem01:02:47

from whatever your main namespace is.

arrdem01:02:10

because (get (ns-aliases *ns*) 'user) is whatever the tab completer will see

wusticality01:02:33

strange, it says user #namespace[x.y.z.user]

wusticality01:02:15

i’d add another alias but it’d piss everyone off 😉

arrdem01:02:32

idk yo sounds like this may be a CIDER or nREPL bug.

wusticality01:02:36

did you say you can execute custom clojure when the repl boots up?

wusticality01:02:37

yeah seems so

wusticality01:02:41

maybe i should file a bug

arrdem01:02:45

pls and thnx

wusticality01:02:51

are you a maintainer?

arrdem01:02:22

I’m a contributor to CIDER and a bunch of other stuff but I don’t maintain anything worthwhile.

wusticality01:02:46

i was curious, there’s a helm interface to the repl history etc, but there doesn’t seem to be for cider-find-ns et al

arrdem01:02:00

no ideas there

wusticality01:02:26

oh scratch that, there is for cider-find-ns but not for jump to symbol i guess, because it uses what’s under point?

wusticality01:02:32

thought i’d just be able to start typing which would be ideal

wusticality01:02:37

maybe there’s nothing quite like that

arrdem01:02:39

M-. works just fine…

wusticality01:02:48

is there one where you can just start typing though

arrdem01:02:51

don’t remember what cider’s implementation thereof is called

arrdem01:02:04

no I don’t think there’s an ido or helm style var finder

wusticality01:02:28

that’d be pretty nice

wusticality01:02:45

i wonder if there’s a ivy one

wusticality01:02:50

that’s a pretty common thing

wusticality01:02:59

unless folks are using just like helm-do-ag or something

arrdem01:02:18

I don’t know how much state if any CIDER keeps on the emacs side.

arrdem01:02:30

Most of CIDER is on the other side of nREPL

wusticality01:02:40

helm-do-ag rather

wusticality01:02:42

you use emacs much?

wusticality01:02:08

at any rate, thanks for all your help!

arrdem01:02:37

Sure, hope that was useful.

wusticality01:02:43

oh, i remember another question - is there a separate repl for cljs?

wusticality01:02:55

or am i just fucked there 🙂

arrdem01:02:23

There is a separate REPL - figwheel was how people did that song and dance last I checked but I don’t have much experience on that side of the house.

arrdem01:02:06

Anyway I’m out. Best of luck.

wusticality02:02:40

if anyone else happens to show up in this channel, what’s the proper way to boot up a clojurescript repl, and can you have both a clojure and clojurescript repl going at the same time in emacs?

tanzoniteblack02:02:35

you can have both going; let me see if I can find a good readme on getting that set up right

tanzoniteblack02:02:58

and as an FYI, while that example suggests setting the emacs variable cider-cljs-lein-repl in your .emacs.el or .emacs.d/init.el; I'd actually recommend putting a file called .dir-locals.el in the root directory of your project (i.e. next to project.clj) with the contents:

((nil . ((cider-cljs-lein-repl . "(do (require 'figwheel-sidecar.repl-api)
           (figwheel-sidecar.repl-api/start-figwheel!)
           (figwheel-sidecar.repl-api/cljs-repl))"))))
This accomplishes the same thing, but sets this variable per project, instead of globally

wusticality03:02:20

@tanzoniteblack thanks! so that .dir-locals.el, is that read from cider?

wusticality03:02:41

i assume it’s just arbitrary elisp

tanzoniteblack03:02:21

It's a emacs thing, nothing cider specific

stardiviner03:02:15

This problem is really weird.

stardiviner03:02:36

Is there some elisp guru want to check it out?

wusticality03:02:08

@tanzoniteblack when is that file being loaded? and by what package?

tanzoniteblack03:02:44

Umm... Going offline now for family time, but it's a built in emacs thing, no special package https://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html

wusticality03:02:31

thanks i’ll take a look

Daniel Hines16:02:07

I'm brand new to emacs using spacemacs and cider. I'm running into this issue where when I send an expression for evaluation at the repl, one of my CPU cores jumps up to 100% usage, and spacemacs freezes totally. Killing the process, restarting, and evaluating that same expression seems to work fine (making me think I didn't necessarily create an infinite loop in my code). Any ideas?

gonewest81818:02:23

So it happens once in a while, but not every time? And not necessarily the same expression?

mikerod18:02:00

I feel like I’ve seen a similar odd long pause “at first” before, but I can’t recreate and I’m not sure what the issue was. I think I just upgraded around then when new versions came out and it magically vanished.

gonewest81818:02:27

What version of cider does spacemacs install?

dpsutton18:02:32

Someone put an issue that they saw this when they ran lein repl outside of a project

dpsutton18:02:41

Abo abo I think

gonewest81818:02:00

At the time it wasn’t reproducible, according to the ticket.

gonewest81818:02:57

You have good memory recall, @dpsutton

dpsutton18:02:01

Don't have time to commit as much due to school and full time job so I try to at least follow along

Daniel Hines19:02:11

Thanks for the input, @dpsutton , @gonewest818. I'm less confident now than I was initially that I'm not just creating infinite loops. In any case, discovering that spamming C-g quickly remedies things has got me back in business for now. I'll keep a watch of that issue and keep looking around if the problem persists.

dpsutton19:02:25

always feel free to ask questions here. never a bother 🙂

gonewest81820:02:37

Another thing to watch out for is printing excessive output to the repl. There are settings you can use to limit repl output (`*print-length*` and *print-level*), and starting with CIDER 0.17.0, I’m pretty sure CIDER will override those settings even if you’ve configured them in ~/.lein/profiles.clj. See https://github.com/clojure-emacs/cider/issues/2160

gonewest81820:02:15

But if you’re using CIDER 0.16 and you haven’t configured those settings, then I would watch for things that print long lists to the repl. (e.g. (range N) with a large N, or an infinite (range))

tanzoniteblack23:02:12

@triss https://clojurians.slack.com/archives/C03S1KBA2/p1519255131000429 set the emacs variables cider-repl-use-pretty-printing to t and cider-pprint-fn to 'pprint