@shaunlebron I used to use it but removed it.
It created too many edge conditions in IntelliJ in non-standard editors.
Actually yesterday I found an annoying side effect of not having it enabled, though:
(my-fn x y|)
I press enter, but I’m planning to continue entering more parameters for my-fn
.
(my-fn x y)
|
I end up with this. But I can’t remember the parameters, so I ask for parameter info. But Cursive doesn’t show it since I’m no longer inside the function invocation.Worse, that call is probably nested inside some other call, so I’ll probably get the param info for the outer call, which is confusing.
I assume the same applies to Emacs et al
@cfleming: thanks for the example
incidentally, that case is handled by the patch I landed today that replaces previewCursorScope
paren mode is run whenever a leading close-paren is found
you can see the new behavior in the demo: http://shaunlebron.github.io/parinfer/demo
v3 isn’t released yet, but will at end of the week
I still haven’t commented on your v1 vs v2 issue, sorry, but in general I agree with Chris - keeping things balanced seems like a fundamental promise parinfer makes.
that’s the last issue I’m going to address hopefully tomorrow
Inserting unbalanced close parens should just not insert anything IMO.
yeah, that’s currently landed
i feel good about the new inline inference that’ll fix the rest of it to keep it balanced
@cfleming: btw I think the new linter will help fix the race condition in intellij that prevented paren mode from preprocessing a file
I meant to ask you about that actually - how would that help?
well, I mean, if a team agrees to run paren mode on all their files before committing, that tool lets them do that
but more than the tool is the accompanying readme to help clear up the types of changes and to help convince people it’s not a bad idea to use it
more concretely: cursive won’t have to process files with paren mode if it’s already processed before opening
Ah, ok, thanks.
I’m still convinced that some kind of local processing will ultimately prove to be more palatable.
But I haven’t had time to prototype it yet.
i.e. only processing the range of sexps touched by the deltas of a change.
Working out that range is actually a pretty hard problem I’m hammocking at the moment
that would be very valuable
If you can do that, then you don’t need to pre-process, and you could just show a warning if the range actually affected isn’t indented correctly.
so it would be a stateful thing to track which lines are changed? and only process those lines?
So this is tied in with how IntelliJ does things, and I’m not sure how generally applicable it will be.
But yes, as a tldr
In IntelliJ, I’m not reacting to specific actions. I see a fair amount of the parinfer doc/online literature referring to “on keypress” or “on <some specific thing, like paste>“. I can’t really do that, since there are far too many actions for me to be able to reasonably anticipate them.
I basically have to react to document changes, so on a doc change I get: change position, old length, new length, old text, new text.
I’d keep track of those for a particular change, which is basically an undoable thing.
This is trickier in IntelliJ than in most editors, since something like a rename can affect a lot of locations in the file, or even across multiple files.
The difficulty tracking modified ranges is that each new change creates a new document “co-ordinate space”, so if I want to get an sexp range from the original document which was affected by a series of deltas, I have to map them all back through the previous changes to get the correct range in the original doc affected by each change.
Then, once I have those ranges I can work out the sexp ranges which cover them all, and then I have to map that forward to get the correct range in the resulting doc.
makes sense, yeah
😕
on keypress => any change, would be a fair mapping I think
not sure about others
Yeah, pretty much - it’s actually a hard problem, especially to do it efficiently - it’s quadratic in the number of changes, and for something like a file reformat that can be a lot.
Not sure if I can special case reformat, and just process the whole file at that point.
Well, keypress is just an action, and some keypresses are more complicated than others and can lead to reformatting changes (tab, backspace, delete, enter)
well, it should really reformat on any keypress
I mean that the IntelliJ action will format things, before I get to see it.
Or at least, the resulting reformatting will be part of the changes communicated to me via document events.
oh, yeah, that’s not good
I’m actually curious how this works in e.g. Emacs. A lot of the complexity in the IntelliJ integration is around making it work in a very general way, since I can’t anticipate all the changes that either IntelliJ or any installed plugins might make.
But the same must apply to Emacs if someone is using clj-refactor - a particular action can cause a lot of changes to be made in multiple places/files.
And people extend Emacs such that a particular action does crazy things all the time. Are those people just not using parinfer?
@cfleming: it was recently added to spacemacs as a core plugin I think
So it looks like the Emacs integration only runs on one of a hard-coded set of commands.
Unless I’m missing something, my elisp is not great.
i can’t tell by skimming right now
looks like it’s only executed from these keys though: https://github.com/DogLooksGood/parinfer-mode/blob/master/parinfer.el#L1078-L1101
I use parinfer in spacemacs/main (that PR is still in develop), setting it up was fairly straightforward
I use it alongside smartparens and paredit
@mattly: cool, does it work well?
@shaunlebron for me it does. I've been slowly moving off of spacemacs (though I still use spacemacs for work) and I just setup parinfer by itself and it feels off
I'd link my config but for whatever reason the slack electron app decided to stop interacting with my system clipboard
@mattly it might feel off due to lack of structural editing stuff
but it was always my hope that it would be compatible if you want add those layers, so glad it’s fitting okay
yeah, paredit is next on my list of things to setup
parinfer has been a helpful sell to my lisp-phobic co-workers that come and pair with me though
🙂!
what type of lisp are you using? and how are you introducing it to your project? (kind of interested in how folks do this)
it's.. a bit odd, really; Clojure/Script, in a group that's otherwise Rails/Ember/Elixir
my project is somewhat alien compared to what everything else is, it's a free-from analytics tool for asking questions from a variety of HIPAA-protected data sources
whereas all the other projects in the group are closed-ended tools for accomplishing specific tasks
before I came on, one of the other senior devs had tried prototyping this project in rails/ember and it was a mess
my specialty is this sort of thing – interfaces for doing data analysis – and I had enough trust from the dev team (most of whom I've known for a while) to make a strong case for doing this in clojure/script, and it's been a huge success in that regard
the original prototype centered around a single type of query from a single datasource, and it had like 2000 lines of string concatenation in ruby to construct a sequel query
I boiled that down to 20 lines of logic and 100 lines of data in clojure
and that got people interested
🎉
trust + direct comparison to show benefit
yeah
I've gotten one or two of the fronend people on another project interested in re-frame
they're both using Atom, so of course I set them up with parinfer
yeah? what do you think their general impression is?
they think it's neat but have a hard time understanding how to build something complex in it
oh, of parinfer, not re-frame
one of them said, "ok, so you were right, the parens aren't really that big of a deal"
sweet!
I tried getting david to make the cljs repo compatible with parinfer, but it was kind of a big ask to add so many whitespace changes without some kind of evidence that newcomers are using parinfer
I’m going to setup some kind of survey asking for people to share stories like this to help build a better case
cool deal
@shaunlebron biggest use for me in parlinter was just identifying dumb indentation mistakes.
@dominicm yeah, your point about revealing “confusing indentation” made it into the parlinter readme, i thought that was a good way to say that
we actually caught an accidental expression nesting in the cljs repo using it
My #1 comment about parinfer is always: > Parinfer puts parentheses where they look like they should be. I've found so many bugs by locating the indent button in people's editors. Parinfer solves this
maybe a good example of this—the mistake caught in cljs repo:
;; before
(is (= nil (s/index-of sb "z" 100))
(is (= nil (s/index-of sb "z" -10))))))
;; after
(is (= nil (s/index-of sb "z" 100))
(is (= nil (s/index-of sb "z" -10))))))
yeah, indentation was wrong
I've had a few instances of that as well
That's a perfect example.
when parens are inferred, i think the question most people ask is—so why are they even there?
i showed the project to jeremy ashkenas before i had a fancy website for it, and his reaction was “…so i guess the next step is to remove the parens”
i kind of got a blank stare when i tried to explain the benefits of explicitness and consistency, but I think it remains the second half of the problem of introducting lisp—that parinfer only elucidates the how of parens rather than the why
... oh god
fleeing from coffeescript's indecisiveness is what drove me to lisp
it’s definitely what drove me back to js
i think it was a great experiment that took philosophy of implied behavior to its extreme, and taught me that it’s not a very good thing for a language to have
agreed
it also taught me how to market a new idea in a very straightforward way
that website was so good
RE "why are they even there"
https://srfi.schemers.org/srfi-110/srfi-110.html also interesting
I’d be interested in reading why those never caught on