Fork me on GitHub
#cursive
<
2017-05-20
>
Lone Ranger00:05:25

so @kzeidler I've run into this problem before and the best workaround I've found is to create a project on the command line using lein and then new project from existing sources in intellij

Lone Ranger00:05:30

I realize that's not a definitive answer or even addressing the underlying cause but it seems to work for me 😅

kzeidler00:05:57

@goomba that did the trick! Do you happen to know if new project from existing sources is a valid option from the IntelliJ init popup? (Or even better: how to disable that f$*&ing popup? 😬)

Lone Ranger00:05:41

😅 no it's a bit of dark magic for me and depends on whether I properly exit or rage quit

Lone Ranger00:05:10

I always go through the menu just b/c it's the only way I know how

Lone Ranger00:05:20

although IIRC there is a way to do it from the popup

kzeidler00:05:11

The only available context for selecting that option (that I'm aware of) is File > New, but the application tabs aren't available until you open something... :face_with_rolling_eyes:

Lone Ranger00:05:25

ohhh I see what you mean

Lone Ranger00:05:23

I think the "import project" would probably do the trick

Lone Ranger00:05:25

from the popup

kzeidler00:05:35

heh yeah. I've looked this up before because it also prevents opening directories from command line. I didn't find a promising lead though 🙂

kzeidler00:05:45

I'll give that a shot

Lone Ranger00:05:49

yeah that seems to work

kzeidler00:05:35

Thanks so much for the tip

Lone Ranger00:05:28

hehehe no worries 😄 it's all these little hangups that prevent actual code writing... I spent six hours yesterday tearing my hair out trying to get datomic running until someone pointed out I wasn't escaping an ampersand in my shell command 😳

Lone Ranger00:05:09

and let's not even talk about kubernetes... 3 months later and I'm still not too much further with that

kzeidler00:05:21

Hahaha that's rough. Did Cursive/IntelliJ not pick up on that?

Lone Ranger00:05:33

well I was editing on emacs soooo.... no 😛

Lone Ranger00:05:46

also, I have almost no idea how to use emacs

Lone Ranger00:05:06

sometimes I'm amazed people pay me money

kzeidler00:05:37

Heh realtime error highlighting is one of those small things that I've noticed several editors really struggle with (cough coughATOM cough)

kzeidler00:05:22

Not IntelliJ though. IntelliJ is more than happy to criticize my shortcomings

Lone Ranger00:05:01

I actually started with PyCharm and good lord it made me seem like a genius compared to folks using other IDEs if for no other reason than alt+enter, error highlights, and code cleanup

Lone Ranger00:05:10

I've dabbled with writing a few plugins... it's not easy. 🎩's off to @cfleming for crushing it with cursive... must've been madness

kzeidler00:05:05

I am. so. mad. I didn't know about IDEs when I was taking CS, everyone else had a sixth sense for solving all the endless strange errors of the JVM meanwhile I was using sublime and perpetually lost

kzeidler00:05:07

how was getting started with that -- writing plugins, I mean?

kzeidler00:05:04

as a lisper I'm always partially thinking about what sort of environment macros would make my life more pleasant

kzeidler00:05:57

lately I've been using bash scripts with my projects, but... y'know. \shudder\

Lone Ranger01:05:43

ohhh yeah that's rough

Lone Ranger01:05:51

what are you bash scripting for? deployments or what?

Lone Ranger01:05:59

I've been using ansible for some of that stuff. It's a pretty good trade off between learning curve and usefulness... way better than just plain 'ol bash scripting so far

kzeidler01:05:44

the other day I was trying to figure out a way to associate only the most recently modified file in a directory with a particular variable

kzeidler01:05:52

there might be multiple ways of doing it, but I ultimately just wrote a bash alias to return the absolute path of the most recently modified file in a particular dir, and just called that from Python

kzeidler01:05:08

but I felt dirty afterward, like I needed a shower

Lone Ranger01:05:50

haha yeah 😅 I end up doing a lot of bash/Python interop for that file system stuff

Lone Ranger01:05:05

at least you're in good company... that's pretty standard these days for sysadmin stuff

kzeidler01:05:57

"modularity? pfft who needs it!"

kzeidler01:05:30

I've asked like half a dozen elder programmers how it was that bash came to be the lingua franca of the shell scripting languages, and scheme did not

kzeidler01:05:49

no one seems to know the answer, they're as baffled as I am

Lone Ranger01:05:29

well after I started learning Clojure I was like "why the hell did we adopt C if we had LISP around in 1960?"

Lone Ranger01:05:55

the answer, at least as far as I can tell, is LISP in the 60's was nothing like Clojure today

kzeidler01:05:53

I actually heard Dick Gabriel talk about this a few years ago (one of the OG creators of Lisp)

Lone Ranger01:05:17

oh yeah? what did he have to say about it?

kzeidler01:05:06

In his assessment the beauty of Lisp was also its downfall, and the ease of extending the primitive base functions led to speciation between the various universities using Lisp, making their programs impossible to decipher outside the local context

kzeidler01:05:34

which... on bad days, reminds me a little bit of Clojure 🙂

Lone Ranger01:05:16

ah, yeah. that's a thing

kzeidler01:05:42

Basically it cleaved into a bunch of local DSLs, see Common Lisp vs. 100s of other lisps

Lone Ranger01:05:58

that's also in general what I've heard described as the "downfall" of LISP in general... it's so much fun to write everyone wants to write everything from scratch

kzeidler01:05:18

The entire interview is actually one of my favorite programming-related things ever http://www.se-radio.net/2008/01/episode-84-dick-gabriel-on-lisp/

Lone Ranger01:05:22

whereas in other languages it's so painful everyone relies on shared code to a much greater extent

Lone Ranger01:05:31

cool! thank you!

kzeidler01:05:22

He's fascinating, just the kind of person you would imagine might have invented Lisp one day

Lone Ranger01:05:08

great intro music

Lone Ranger01:05:09

whoa... MFA in poetry

Lone Ranger01:05:13

didn't see that one coming

kzeidler01:05:23

right!? He's a unicorn

Lone Ranger01:05:58

whoa... the way he talks about the initial thought of LISP is exactly why I became interested in Clojure... code that constructs code

kzeidler01:05:07

Totally. Sometimes in 2017 I forget to remember that the base mechanism of lisp is beautiful and a nice idea, despite circular dependencies and bizarre errors thrown from external sources 🙂

Lone Ranger01:05:10

happily I don't know enough about it yet to worry about those problems

Lone Ranger01:05:24

although so far my experience with dependencies has been much nicer than Python

Lone Ranger01:05:47

I can see now why folks coming to Python as a second language find it maddening

kzeidler01:05:33

I know their pain... for what it's worth, once I switched to anaconda I stopped having strange dependency issues

Lone Ranger01:05:02

Ahhh.... yeah anaconda introduces other issues though

Lone Ranger01:05:34

really the only way to do it without fubarring everything is to use VMs and containers for Python (or else virtual environments (which I think are dumb))

kzeidler01:05:24

Does it? What kinds of issues?

Lone Ranger01:05:27

wow, I just instinctively closed out nested parenthesis

Lone Ranger01:05:41

it's too late for me

Lone Ranger01:05:31

so with anaconda... if you want new packages you should use the conda tool

Lone Ranger01:05:55

if you're trying to use pip or easy_install and you're not careful you can install to the wrong place and it's not obvious

kzeidler01:05:06

really the only issue I've had with conda is certain libs like Tensorflow don't seem to be able to compile themselves to your individual machine, and supposedly would be a lot faster if installed directly via Pip

Lone Ranger01:05:30

you running a windows machine?

Lone Ranger01:05:36

if so anaconda is really the only way to go

kzeidler01:05:45

weird. What's the defined behavior exactly when 'pip' is called in a conda environment?

Lone Ranger01:05:04

it seems arbitrary

Lone Ranger01:05:26

I find that libraries that are installed using anaconda tend to install to anaconda

Lone Ranger01:05:42

which is fine until it's not

Lone Ranger01:05:58

again I just skirt the issue with containers/VMs

Lone Ranger01:05:34

lol and now I'm starting to do a lot of Python/Clojure interop

kzeidler01:05:15

Haha I do run into periodic issues with the permissions of like, python development header files especially

Lone Ranger01:05:55

basically the only things I won't do in Clojure anymore are sysadmin/devops stuff and anything I need numpy for

kzeidler01:05:12

but they usually go away once i do something horrible like chown all my python paths and chmod them so everyone and their mother is invited to use them

Lone Ranger01:05:21

ahhaaahaaaaaa

Lone Ranger01:05:30

I'm so glad I'm not the only one who does that

Lone Ranger01:05:54

f*ck it chmod -R 777 .

Lone Ranger01:05:17

actually I've done chown -R 777 . and that's not fun

kzeidler01:05:21

my dev environment is a total house of cards and yes I live in constant fear of it toppling 🙂

Lone Ranger01:05:07

you know before I became I programmer I assumed all programmers were like Dick Gabriel

kzeidler01:05:32

oh snap, haha does that do what I think it does? Give your files to someone named 777?

Lone Ranger01:05:40

now that I've seen the man behind the curtain ... every profession I once assumed was full of competent people has been called into question

Lone Ranger01:05:56

other way around

Lone Ranger01:05:09

chmod -R app .

Lone Ranger01:05:30

changes everything to ????????? <file-name> when you run ls -l

kzeidler01:05:38

hahahahahah

Lone Ranger01:05:13

suddenly nothing works

kzeidler01:05:17

Are you even allowed to touch them after? You must be, right?

Lone Ranger01:05:25

yeah with sudo

Lone Ranger01:05:08

I remember before I was doing automatic deployments I botched a deployment pretty badly and had to go in and modify the live production system and did that

kzeidler02:05:21

btw, the solution for the issue we discussed earlier appears to be: left click your project.clj > add project to leiningen (or something like that), it should then start reindexing everything and when finished you should be able to specify a valid run configuration for the REPL

Lone Ranger02:05:47

and the recursion unwinds 😄 wonderful!

cfleming04:05:50

@goomba No, I’ve been meaning to fix that but right now you have to use the “evaluate expression” popup you found.

cfleming04:05:07

The issue is that the REPL is suspended because the whole VM is stopped.

cfleming04:05:45

@timgilbert There isn’t, I’m afraid - that’s a fundamental part of parinfer (see https://shaunlebron.github.io/parinfer/#downsides)

cfleming04:05:10

I’m halfway through thinking about/planning a parinfer-like thing which only works locally, and would not suffer from this problem.

cfleming04:05:03

@kzeidler Phew - read all that. I think the issue is how you’re creating your projects. For a simple one-`project.clj` project, the easiest way is just File-&gt;Open… and select either the project.clj or the containing directory.

cfleming04:05:52

If you want to create a new project from within IntelliJ, File-&gt;New…-&gt;Project, then select Leiningen and you should be good to go.

cfleming04:05:07

@kzeidler There’s some doc about this here: https://cursive-ide.com/userguide/leiningen.html. It’s slightly out of date since it was written against an older IntelliJ version, but it should still help.

Lone Ranger04:05:04

Thanks again boss @cfleming, my hero as always!

puzzler04:05:26

@cfleming Looking forward to the day I can try your new take on parinfer. I've temporarily gone back to emacs, in large part because I'm really liking parinfer, and Cursive's implementation of parinfer is too quirky for my tastes. I've mentioned this before, but in case it's fallen off your radar, I'll say that my three big issues with Cursive's parinfer were: 1) there is no "paren" mode, and parinfer really relies on being able to toggle back and forth between paren and indent mode. Cursive offers parinfer's indent mode, but Cursive's plain editing mode isn't really an adequate substitute for paren mode, IMHO. 2) I had files corrupted when Cursive's parinfer relocated parens based on indentation without asking for permission or formatting the file first (as a consequence, for example, of jumping to definition triggering another source file to be opened). 3) Undo interacted in strange ways with parinfer.

cfleming04:05:40

@puzzler Thanks. After that recent thread I’m motivated to try to make Cursive more beginner-friendly again.

cfleming04:05:01

Cutting and pasting is another pain point, which may have a simple solution.

puzzler04:05:47

@cfleming The other thing I'm really liking in emacs is how trivial it is to start up both a clojure and clojurescript repl for a mixed-code project. In pretty much every other respect, I'd prefer to be using Cursive. I'm sure I will be back on Cursive at some point in the future.

cfleming04:05:14

@puzzler Yes, a combined clj/cljs REPL is the next large feature I’m planning.

puzzler04:05:25

@cfleming Glad to hear it.

puzzler04:05:02

And yes, cutting/pasting was another thing that interacted oddly with parinfer at times. I had forgotten about that.

rauh12:05:30

Just tried out 2017.1.2, and with it, "Jump to namespace" dialog often immediately disappears after a fraction of second. Not an issue with 2016.3.2

kzeidler13:05:48

@rauh Yeah that's a minor gripe I have with IntelliJ itself. I've always had that problem, I think it's an IntelliJ quirk (also any changes to my tooltips' delay parameter do... nothing, I think)

kzeidler13:05:20

I have a dream, which may or may not be possible. But I bet it is possible: I'd like to have two simultaneous REPL run configs in the same project, one synced with the project.clj, and the other synced with some provisional staging REPL that I can use to hack on libraries that I'm considering introducing to the main build config.

kzeidler13:05:28

I know with leiningen it's mandatory to restart the repl after introducing a new dependency, which can be a headache. I'd like to minimize the number of times I have to stop/rebuild/reboot the main REPL process while I'm still flirting with a bunch of different libraries that I may or may not end up using

rauh13:05:37

No restart necessary

rauh13:05:14

I've never used "start repl" from Cursive, I only ever connect to the NREPL that I start on the command line.

kzeidler14:05:15

Hmm... I'm a little timid about introducing a dynamic dep fetcher/loader into my project at this point. I'm still a little scarred from using Boot a few months ago... I ended up retreating back to Javascript for a while

kzeidler14:05:18

@rauh You don't use the Cursive REPL that's built into IntelliJ at all? 😮

rauh14:05:13

No I do, I just don't start a REPL from Cursive, I just connect to 3 different REPLs

rauh14:05:01

So for your case, you can start 2-3 REPLs on the command line and send forms to the REPL where you want to try out a library

kzeidler14:05:08

Innnteresting... I'm trying to picture this, but I'm having trouble visualizing how that even works

kzeidler14:05:27

I think I'm starting to see

rauh14:05:55

So you start and NREPL, lein with-profile dev-clj repl :start :host localhost :port 23134

kzeidler14:05:14

So the primary REPL basically... broadcasts the input to some slaves or something on the slave ports?

rauh14:05:52

And in cursive you do "Clojure REPL -> Remote"

kzeidler14:05:08

And the slave environments are each customized and self-contained, I guess?

rauh14:05:37

yeah, Cursive stays lean and doesn't start anything by itself.

rauh14:05:17

I can even REPL in my Clojurescript macro namespaces. IMHO that should really be the recommended way, easier and more powerful

kzeidler14:05:22

I've spun up a remote REPL before... that's just a REPL listening on a network port right? Is there anything more to it than that?

rauh14:05:43

nope, that's it.

rauh14:05:29

With the workflow you can even load new clojurescript libraries onto the classpath at runtime without ever restarting figwheel or any REPL

kzeidler14:05:42

Haha and they just chat with each other and debate the interpretation of language expressions indefinitely. Neat.

kzeidler14:05:15

Is there a practical limit on how many remote REPL processes you can run concurrently?

kzeidler14:05:28

I'm sure it's not a hard limit

kzeidler14:05:34

but these handsome bastards seem to require about 1GB of ram while the processes are actively working

rauh14:05:48

My Shared memory is at pretty much 90% of each lein process

kzeidler14:05:47

The remote repls are able to share memory? Whaaaat

rauh14:05:26

Well that's just Linux doing it's work

rauh14:05:40

So I just started 10 REPLs and RAM increased by 200 MB

kzeidler14:05:33

Actually I can see how that would make sense... remote repl doesn't remotely execute anything, it's just remotely listening. Is that right?

rauh14:05:49

Well, TBH, the above 200MB were probably because linux freed some RAM somewhere else 🙂

kzeidler14:05:15

It's hard to say for sure, but it looks like there should be a way to implement multiple remote repls in the run config menu itself (no dependencies required)

rauh14:05:39

What do you mean?

rauh14:05:53

You can have multiple remote repl configurations in Cursive, no problemo

rauh14:05:18

The REPL is just a Java+Clojure process

kzeidler14:05:36

In the run config menu there's an option to spin up a remote REPL at a designated host, port, from a designated "context module file"

rauh14:05:43

though the jar files aren't loaded n times, but are all in shared mem

kzeidler14:05:45

gotcha. Yuss

rauh14:05:49

Though, the objects living in the processes will still all add up. But you can restrict the JVM and it'll stay leaner

kzeidler14:05:50

currently I only have the option of selecting one context module, which aligns the current project's project.clj namespace/version number

kzeidler14:05:05

Is there a way to import non-local context modules?

kzeidler14:05:46

(e.g., a dummy project clj that just loads a new library that I want to play with, maybe some utilities from the current project but not the whole running server part)

rauh14:05:45

You mean so Cursive knows about your deps? Yeah for that I merge all my deps from the REPLs into one for Cursive to read.

kzeidler15:05:45

@rauh: you wouldn't happen to know if defining those satellite REPLs as named build profiles (so the alternate dependency sets are scoped to the main project.clj) might be another way to implement this? Would building a project with multiple profiles compile down to one self-contained "context module" thingy per profile? Struggling a bit to get this off the ground, but from what I gather this looks like maybe the preferred way to deal with multiple environments

rauh15:05:42

@kzeidler Not sure what you mean, can you make an example?

kzeidler15:05:32

@rauh: sure, so if the following defines the project.clj, and building the project.clj produces a my-namespace.core-v.1.0.0-SNAPSHOT object, and a SNAPSHOT object is required to initialize the Remote repl via run configs, is there some way to easily instantiate one of either the :dev, :secondary, or :tertiary environments in the run config? `(defproject ring_to_curl "0.1.0-SNAPSHOT" :description "FIXME: write description" :url "http://example.com/FIXME" :license {:name "Eclipse Public License" :url "http://www.eclipse.org/legal/epl-v10.html"} :dependencies [[org.clojure/clojure "1.6.0"] [cheshire "5.4.0"]] :profiles {:dev {:dependencies [[com.cemerick/austin "0.1.5"] [com.cemerick/piggieback "0.1.4-SNAPSHOT"] [ring-mock "0.1.5"]] :plugins [[com.keminglabs/cljx "0.5.0"] [com.cemerick/austin "0.1.5"] [lein-cljsbuild "1.0.3"]] :test {}} {:secondary {:dependencies [...other deps] ... other plugins }} {:tertiary {:dependencies [...and so on]}}})`

rauh15:05:36

use triple quotes

kzeidler15:05:21

I'm assuming that the motivation for partitioning the different environment profiles like this is basically what I'm trying to do too... share whatever definitions ought to be shared, and enforce separation between the parts that need to be separated. But I'm quite over my head 😅

rauh15:05:35

@kzeidler Here's how my project.clj looks like, it works nicely with Cursive: https://gist.github.com/rauhs/d5bb47c239b58cbf54e1d3d1de221031

kzeidler15:05:28

@rauh: really helpful. Thanks for pasting them

sandbags19:05:12

@cfleming what controls when cursive can lookup a symbol that cannot be resolved in the current file and find it in another file. So if I have foo/bar sometimes it will pop up the intention (?) "Do you mean bar in namespace x.y.z.foo"? And create the appropriate require for foo so that the symbol can be resolved. But I can't seem to figure out why sometimes it doesn't.

tcarls21:05:22

Is there a canned configuration available that'll be comfortable to folks with finger memory from Emacs Live or similar environments? The way paredit works in Cursive is different enough that I find it quite unwieldy (as in, gave up and switched back to Emacs the last two times I tried it).

kzeidler21:05:59

@cfleming: just wanted to say this parinfer is so far the first parinfer I haven't rage quit within the first 10 minutes of use. It's wonderful! Seriously, major props. I bet the logic is quite beastly