cursive

Issues at: https://git.io/cursive-issues
Jakub Holý 2020-09-10T13:11:06.058900Z

How is it possible that I def-ine a var in the REPL window but it is then undefined? My session:

*ns* 
=> #object[clojure.lang.Namespace 0xfcdc79d "user"]
(def s1 "To work with module.rds-st2.module.rds.random_string.suffix its original") 
=> #'user/s1
(re-find #"To work with (module[^ ]+)" s1)
Execution error (ClassCastException) at user/eval72482 (form-init11451571577345478644.clj:1).
class clojure.lang.Var$Unbound cannot be cast to class java.lang.CharSequence (clojure.lang.Var$Unbound is in unnamed module of loader 'app'; java.lang.CharSequence is in module java.base of loader 'bootstrap')
(re-find #"To work with (module[^ ]+)" user/s1)
Execution error (ClassCastException) at user/eval72486 (form-init11451571577345478644.clj:1).
class clojure.lang.Var$Unbound cannot be cast to class java.lang.CharSequence (clojure.lang.Var$Unbound is in unnamed module of loader 'app'; java.lang.CharSequence is in module java.base of loader 'bootstrap')
s1
=> "To work with module.rds-st2.module.rds.random_string.suffix its original"
user/s1 
=> #object[clojure.lang.Var$Unbound 0x2363d6f "Unbound: #'user/s1"]
Update It seems it was Shadow-cljs' cljs REPL and the app has likely not been running anymore so that could perhaps explain it...

2020-09-10T13:15:18.059700Z

That was definitely a weird one

kennytilton 2020-09-10T14:16:27.064400Z

Is there any way for us to extend the Cursive editor? On of the great tricks I learned thanks to an old skool Lisper was a surprising mouse-copy command that at first seemed bizarre and then became pretty much how I edited, esp. when refactoring: https://github.com/vsedach/mouse-copy We leave the insertion point where we want to (in effect) paste some code, then control-click or alt-control-click what we want to copy. Utterly counterintuitive and utterly addictive. Cursive rocks, but I miss this! 🙂

cfleming 2020-09-13T04:54:00.077800Z

https://github.com/cursive-ide/mouse-copy

cfleming 2020-09-13T04:54:32.078100Z

Give that a try! I’m unlikely to support it much, but if it doesn’t work let me know and I’ll see if I can take a look. That was definitely harder than I expected.

cfleming 2020-09-13T04:54:47.078300Z

@hiskennyness ^^

kennytilton 2020-09-13T07:05:08.078500Z

Sorry, I was away…thanks!!! Too awesome for words. Don’t know if you solved it already, but c-leftclick copies (leaving the original intact) and c-m-leftclick moves the original. I will give it a try now. If it needs work/support I will give it a shot. I guess my bigger Q was how to modify Cursive. Brilliant! 🙏

cfleming 2020-09-13T07:19:15.078700Z

@hiskennyness Great! Let me know if you have questions. If you want a copying and a cutting version, I’d create separate actions and factor the common code out, so you can assign different shortcuts. Ctrl-leftclick is probably caught at a very low level, particularly on OSX, for showing context menus. The other thing you might want is reformatting either the source or destination locations after pasting, let me know if that’s something you might want, it’s pretty easy to implement. Don’t be afraid to ask if you have questions!

cfleming 2020-09-13T07:20:13.078900Z

Note that this doesn’t extend Cursive directly at all, just uses standard IntelliJ machinery. So you can also use this to do the same in e.g. Java if the mood takes you 🙂

kennytilton 2020-09-13T07:24:56.079100Z

OK, right, I have to fight the Mac for the keychords. 🙂 I guess it could be the right or middle button if I go get a 3-button mouse. I have an Apple mouse which at least has the right click. Thx again for the effort. I know this is a counterintuitive mouse gesture but once I got into it it was all I did while refactoring.

cfleming 2020-09-13T08:02:19.081Z

Not only the Mac but also IntelliJ, that has actions bound to all the common key combinations with the left click, at least.

cfleming 2020-09-13T08:05:21.081200Z

I’m actually not sure if you can reuse Ctrl-click if you have an external mouse connected, you’ll probably need to play around with that and maybe look in the debugger to see what the events end up looking like.

cfleming 2020-09-13T08:06:19.081400Z

That code is pending a code review from the guy at JetBrains who was helping me with it, I’ll let you know if there are changes to it.

kennytilton 2020-09-13T08:53:02.081800Z

Oh, wow, this is great support. I had to upgrade to 2020.1 and have encouraging results, with some issues: • the context menu still pops up; and • the text is copied where the click (to copy) is made, not to where I left the insertion point. I am starting to dig into the JB doc, but quickly: is it possible to develop interactively, or is the flow to edit, rebuild plugin, and re-import? Thx again for the effort and JB’s effort as well.

kennytilton 2020-09-13T13:27:22.082300Z

Ah, you mentioned a debugger, sounds like I could hack interactively. I will dig into the docs.

kennytilton 2020-09-13T16:14:16.082800Z

OK, not sure what I did but while thrashing I also got Kotlin upgraded to 1.4, maybe that helped. Anyway, text is indeed now copied to the current point. Also, I stole option-click for this feature and that works without kicking off other things. Sweet, I will try to work this much into fingers’ keychord repertoire. Thx again.

kennytilton 2020-09-13T16:15:45.083Z

I have a couple of feature tweaks that would be nice. Should I put them up on the repo as “issues” or just mention them here?

kennytilton 2020-09-13T18:46:10.083200Z

OK, @cfleming, by hook or by crook I am able to generate debug prints from the plugin. 🎉 First RFE will be to allow copy from a right brace back to the matching left.

kennytilton 2020-09-13T18:47:31.083400Z

btw, I use the “runIde” task to bring up a whole IDE. Is there a simpler/faster way to iterate?

cfleming 2020-09-13T20:39:33.083600Z

@hiskennyness Great! Glad you’re getting into the swing (ha ha) of things. Yes, runIde is what you want, and you want to run it in debug mode. The only interactive option, sadly, is to change the code and then recompile (Build | Build Project), and if you’re lucky the debugger will offer to reload the new classes for you.

cfleming 2020-09-13T20:45:14.083800Z

WRT your two issues above - here’s a bit of background. Normally to add a new action, you’d define an AnAction subclass like the Copy one in this plugin, declare it in the plugin.xml and be on your merry way. This one is more complicated because we need to capture the Swing events very early in the process so that the IDE doesn’t perform other actions based on the mouse click, like moving the caret. So if we don’t intercept the events early, what will happen is that they’ll propagate through the IDE, the editor will move the caret and then eventually our action will be invoked. That will cause this issue: “text is copied where the click (to copy) is made, not to where I left the insertion point”, because the editor moves the caret before our action is invoked.

cfleming 2020-09-13T20:47:23.084Z

So what I suspect is happening is that for some reason the event dispatcher is not catching your event early, or your action is disabled for some reason. You’ll need to debug to figure that out - put the breakpoint here: https://github.com/cursive-ide/mouse-copy/blob/master/src/main/kotlin/mouse/Copy.kt#L127 - that’s the most likely point for the interception of the events to fail.

cfleming 2020-09-13T20:48:44.084300Z

Assuming you catch the event there, debug down to here https://github.com/cursive-ide/mouse-copy/blob/master/src/main/kotlin/mouse/Copy.kt#L150, step in until you reach our update() method here: https://github.com/cursive-ide/mouse-copy/blob/master/src/main/kotlin/mouse/Copy.kt#L82 and make sure that isEnabled is coming out true.

cfleming 2020-09-13T20:51:01.084700Z

BTW for debug logging, your best option is to set a breakpoint which doesn’t suspend, but which does log to the console (see under Breakpoints’ properties -> Suspend and Logging options here: https://www.jetbrains.com/help/idea/using-breakpoints.html#breakpoint-properties)

kennytilton 2020-09-13T22:45:27.084900Z

Thanks for all that! It started copying to the right place. Only thing that changed was a Kotlin upgrade to 1.4. shrug. And I managed to do print debugging by creating a run config from the runIDE task. A bit heavy handed but it let me explore a little. 🙂 I studied your code and looked at the API, and just played with normal editing. I noticed the Kotlin editor does not support double-click select on a right brace. Started getting pessimistic, then I had an insight.

kennytilton 2020-09-13T22:54:57.085100Z

What is needed is exactly the logic that determines the range to select when we double-click. In IJ/Cursive that will either identify a grouping (brace, bracket, or parens) or a word. If we can pilfer that logic, it will identify precisely what to copy or move to “point”. Is that logic (that decides the double-click range) also outside Cursive? In com.code.Insight? If you can help me track that down I’ll work on this next weekend. Meanwhile I’ll have fun with the copy off the left parens. 🙂

cfleming 2020-09-13T23:31:09.085500Z

I’m not sure what you mean by the logic to select the right brace - what is it you’re trying to achieve there?

kennytilton 2020-09-14T14:29:52.087300Z

Well, we can double-click just to the right of a right parens/bracket/brace in a Clojure file and it will select the whole form to the left. Perfect for a Lispy language. In a Kotlin file the editor selects just the character to the right of the closing brace, which actually makes sense typographically given that we prolly are in the bounding box of that glyph when we click to the right of a parens et al. So I think leveraging the codeInsights library may not work for a Lispy language. But something is! The double-click selection range in Clojure is just what we need for mouse-copy. We will not actually get that as a selection and that is good, because any existing selection needs to be replaced by whatever we click (so we need to know what it is). Hmm, I am about to fire up the Lisp editor I use that has this implemented. Should I capture a movie?

cfleming 2020-09-14T20:16:17.089500Z

I see, that demo was very helpful, thanks. So that doesn’t work quite how I envisioned, I thought it worked only for sexps but it also works for other types of form too.

cfleming 2020-09-15T03:17:05.090Z

Ok, I’ve investigated this a bit, and added some features to Cursive along the way that I’ve wanted to do for a while. The double-click form selection is driven by the same logic as the Extend Selection command, which is quite easy to hook into. But I don’t think that’s actually what you want, since that will select various types of intermediate things which are not actually single forms but which are useful to select sometimes, like words in strings and sub-parts of qualified keywords and symbols. I think you’d only ever want a complete atom for this, correct?

cfleming 2020-09-15T03:17:33.090200Z

@hiskennyness ^^

kennytilton 2020-09-15T04:11:03.090400Z

Sorry, I was lost in the history of Lisp over here: http://www.softwarepreservation.org/projects/LISP/resource/#Bibliographies_ I never knew that resource existed! There goes the next month. As for words in strings, (a) lemme check that lisp (btw, that is the AllegorCL IDE on Windoze, they have a free version, but there is an internal flag we have to toggle to get the behavior — I will dig that up, as well) and (b) picking up the whole string would be amazing, but if we fall short of that it is not the end of the world. ISTR just sucking it up when edge cases like that did not quite work. eg, “Fine, I will click the open or close quote” 🙂. brb

kennytilton 2020-09-15T04:12:16.090600Z

ps. just option-clicking left-groupers is already a delight. Thx!

kennytilton 2020-09-15T04:32:00.090800Z

Ok, here is the magic incantation on AllegroCL for Windows if you want to go that far: (setf (cg.base::use-mouse-clicks-to-copy-lisp-forms (configuration cg.base::*system*)) t) And here is that version: https://franz.com/products/express/

kennytilton 2020-09-15T04:43:28.091100Z

Meanwhile, yeah, the AllegroCL implementation is not smart enough to jump out to the whole string, it just copies the word I click. It can also do insane things if invoked within a comment. Basically my attitude was "do not get carried away, and be ready to revert the file". (The undo in that editor barely works.) As for parts of namespaced keywords, heh-heh, that gets me even now when double-clicking, so I am used to the disappointment. 🙂 But yes, I think most users would be trying to copy the whole atom. Good for the "nice to have" category, but not at all essential in my heavy experience of this feature.

kennytilton 2020-09-15T04:54:46.091400Z

@cfleming ^^

cfleming 2020-09-15T04:56:14.091600Z

@hiskennyness I’ve often thought I should download the CL IDEs to try them out, but it comes with a difficult first step which is “Learn Common Lisp” 🙂

cfleming 2020-09-15T04:57:07.091800Z

I don’t think those modifications are hard, I’ll try to make the changes in the next day or two.

🙏 1
🎉 1
kennytilton 2020-09-15T05:01:29.092Z

Heheh, CL is a lot different than Clojure, though also much the same. In my experience, that AllegroCL Windoze version is far and away the best. The Lispworks Free version is also a GUI-ish IDE. ClozureCL no longer works for me, too bad, it was good, too. Overall, I think EMACS+Slime is the predominant favorite by far. btw, the only reason I use Windoze is for that AllegroCL IDE. Their port to *nix did not pan out, and with everyone using emacs anyway….

cfleming 2020-09-15T05:09:03.092400Z

Looks like they have a Mac version though? Is that buggier than the Windows version?

kennytilton 2020-09-15T05:58:05.100800Z

Lemme give it a try. I thought they had given up on the IDE aspect….well, it bravely starts up, has me install GTk, then I just see squares where chars should be. YMMV. The Lisp REPL should be fine, but we’re after the editor.

2020-09-10T15:42:02.065200Z

is it possible to run cljs tests (via lein-doo) in Cursive directly?

plins 2020-09-10T18:10:14.067100Z

hello everyone, is there a way to override cursive’s formatting? force it to use a tool like clj-fmt/zprint?

Eric Casteleijn 2020-09-10T18:44:31.069200Z

👋 another formatting related question: when you tell cursive to format a macro in a particular way, (say, ‘Resolve as let’), where is that setting stored, and is it exportable, or shareable with others in some way?

Eric Casteleijn 2020-09-10T18:46:13.069900Z

Oops asked too soon, my colleauge told me: Preferences > Languages & Frameworks > Clojure > Symbol Resolution shows it.

Eric Casteleijn 2020-09-10T18:52:24.071200Z

@plins if you have either of them as a command line tool, you can configure an ‘External Tool’ to run it.

Eric Casteleijn 2020-09-10T18:53:06.072100Z

I haven’t tried, but I suspect you could then run it automatically on save if you install the Save Actions plug-in.

plins 2020-09-10T18:53:39.073200Z

thanks for the directions, ill try to see if I can make it behave properly

Eric Casteleijn 2020-09-10T18:53:48.073400Z

(Honestly I find configuring Vim easier than Intellij. ;)

cfleming 2020-09-10T23:13:46.074200Z

There isn’t, no. This is because the formatting engine is pretty deeply embedded into IntelliJ, and is used in a lot of actions (for example, when you press Enter it’s used to figure out where in the next line the caret should go).

cfleming 2020-09-10T23:14:10.074400Z

No, unfortunately Cursive doesn’t support running CLJS tests yet.

cfleming 2020-09-10T23:18:20.074600Z

The formatting (“Configure indentation for….“) and resolution (“Resolve … as…“) are stored in different places, but they both use IntelliJ’s schemes mechanism. So under Preferences | Editor | Code Style | Clojure or Preferences | Languages & Frameworks | Clojure | Symbol Resolution, you can choose to share them with the project, export them etc.

🙏 1