parinfer

shaunlebron 2017-06-09T00:33:34.147871Z

sure!

shaunlebron 2017-06-09T00:35:43.164903Z

not crazy about the name

shaunlebron 2017-06-09T00:37:15.176867Z

wanted it to be slightly related to parinfer, without creating an impression that it forces everyone to use parinfer if it’s used

dominicm 2017-06-09T08:33:54.023342Z

@shaunlebron fraction of a second on 40k loc

dominicm 2017-06-09T08:34:54.037268Z

2.5s on 31k loc

dominicm 2017-06-09T08:35:13.041607Z

0.77s on the 40k loc.

dominicm 2017-06-09T08:45:58.192545Z

@shaunlebron changes lgtm. Biggest change on one project was that a bunch of #_-related indents.

dominicm 2017-06-09T09:10:55.554894Z

Not sure if this is intentional, but:

(let [x 1
      ]
  x)
Seems to leave behind an empty line where the ] was

dominicm 2017-06-09T09:17:34.650851Z

also multi-line strings don't get indented. E.g.:

(defn foo
"Hello
world")
(defn foo
 "Hello
world")

shaunlebron 2017-06-09T14:44:05.687150Z

@dominicm thanks for feedback!

shaunlebron 2017-06-09T14:45:54.728833Z

i’ll try adding an option to delete lines that were left empty after linting

shaunlebron 2017-06-09T14:47:01.754423Z

multi-line strings cannot be indented, since that would be adding more literal spaces inside the string, thereby breaking code!

shaunlebron 2017-06-09T14:47:29.765212Z

i’ll add a note about that 👍

dominicm 2017-06-09T14:55:00.939920Z

@shaunlebron yeah, I thought that might be the case. There's perhaps an "edge case detection" where you say "This is all aligned already, and it's inside a defn, let's indent it & warn the user". But I'm not sold on that being a good approach.

shaunlebron 2017-06-09T14:56:22.972892Z

ah, I see what you mean

shaunlebron 2017-06-09T14:56:28.974975Z

for things like docstrings I suppose

shaunlebron 2017-06-09T14:56:50.984020Z

where it doesn’t really matter

shaunlebron 2017-06-09T14:58:02.013030Z

docstrings are a bit inconsistent in the cljs compiler code—sometimes it’s indented to the first ", other times is it’s indented one space to the right of it

dominicm 2017-06-09T14:58:10.016032Z

I know. 😞

shaunlebron 2017-06-09T14:58:14.017804Z

and sometimes it changes within the same docstring

shaunlebron 2017-06-09T14:58:30.024125Z

very hard to detect

dominicm 2017-06-09T15:00:22.071463Z

I think Clojure's multi-line string support isn't necessarily great tbh. I wish I could do:

<<EOS
If you provide "foo" as a parameter…
EOS
for example.

dominicm 2017-06-09T15:00:50.083630Z

I agree, I notice it a lot. I imagine zprint is the tool for fixing that (I didn't check!)

dominicm 2017-06-09T15:02:01.112682Z

it doesn't 😞

shaunlebron 2017-06-09T15:03:03.137625Z

would you throw a reader error if text inside the heredoc was indented to the left of the << ?

shaunlebron 2017-06-09T15:04:20.168874Z

i’ve heard these complaints before, but I’m not sure how people would solve it

dominicm 2017-06-09T15:05:05.187038Z

@shaunlebron I'm sure there's issues 🙂. I'm not really sure what a heredoc is! I just know it would be nice not to have to worry about string escaping at times, for doing expressive docs.

shaunlebron 2017-06-09T15:06:05.210474Z

@dominicm heredoc is the common name for the <<EOS syntax for describing multiline strings

shaunlebron 2017-06-09T15:07:36.245289Z

anyway, definitely don’t commit those linted files yet, the trim will have to know about the original code so it doesn’t remove the other empty lines

dominicm 2017-06-09T15:07:37.245733Z

@shaunlebron ah! I see. I guess the current bash/ruby implementations would be worth comparing against. I don't really feel strongly, I'm just currently thinking about docs. No doubt I'll end up at literate programming.

dominicm 2017-06-09T15:07:51.251165Z

Oh, I already landed that bomb 😉

dominicm 2017-06-09T15:08:13.259211Z

I fixed it manually, vim made it easy enough, especially as I checked every change manually so I'd have feedback.

shaunlebron 2017-06-09T15:08:18.261355Z

ah, the perils of being a beta tester

shaunlebron 2017-06-09T15:08:38.268577Z

cool 👍 appreciate it. good feedback

shaunlebron 2017-06-09T15:09:25.286524Z

@dominicm did you have to negotiate at all with your team?

shaunlebron 2017-06-09T15:09:41.292584Z

and did you integrate it as a check?

dominicm 2017-06-09T15:10:25.309631Z

@shaunlebron I ran it as a one-off for now. No negotiating required. The changes were mostly sane. I also manually reverted a change around https://github.com/shaunlebron/parinfer/issues/92

dominicm 2017-06-09T15:11:10.326491Z

It was easy to use parlinter on the codebase because it's not invasive at all. Nobody is going to fight fixing confusing indentation & moving parens onto the same line.

shaunlebron 2017-06-09T15:12:14.351011Z

I’m documenting the cases where people might fight it

shaunlebron 2017-06-09T15:12:47.364186Z

you’re saying you reverted the comment change to keep the paren after the comment?

dominicm 2017-06-09T15:13:39.383931Z

@shaunlebron yes.

dominicm 2017-06-09T15:14:21.399875Z

I also think using git ls-files -- **/*.{edn,clj{,c,s}} for the list of inputs to parlinter would have been faster, as parlinter probably ran against the compiled files unnecessarily.

dominicm 2017-06-09T15:14:42.407861Z

uh, you suggest **/*.{edn,clj,cljc,cljs} but same thing

shaunlebron 2017-06-09T15:15:42.430873Z

do you think the comment case can be resolved in Indent Mode somehow? that’s a scary thing to me but I’ll try to revisit

dominicm 2017-06-09T15:17:54.481640Z

@shaunlebron I've no idea. I know you didn't like the edge case of it. It's definitely kind of incompatible with parinfer. But it's definitely the sort of thing I see in codebases quite commonly, and removing it isn't really okay where we have it (usually detailing the reasons for elements in a vector, or documenting why some function unexpectedly appears at the end of the threading macro)

dominicm 2017-06-09T15:18:44.500483Z

> quite commonly Rather, I see it often in codebases "at least once". So, I don't see it everywhere. But I usually do see it. Not sure how to word that.

shaunlebron 2017-06-09T15:21:58.574401Z

I suppose (comment) would work better, but would be inconsistent with the other ;; comments

shaunlebron 2017-06-09T15:23:58.621612Z

my concern is that it won’t be integrated as a checker if it fails on an edge case that people want to keep around, and I’ll have to add a ;; parinfer: ignore directive

dominicm 2017-06-09T15:24:04.623789Z

Well:

(-> 10
    distinct (comment This is like this because reasons of #1 XYZ, #2  DEH))
A. syntax highlights B. Triggers the tag reader

shaunlebron 2017-06-09T15:24:26.632580Z

I agree

shaunlebron 2017-06-09T15:24:31.634422Z

maybe as a string

shaunlebron 2017-06-09T15:24:46.640108Z

yeah, it’s just bad

shaunlebron 2017-06-09T15:25:26.655663Z

(-> 10
    distinct) ;; This is like this because reasons of #1 XYZ, #2  DEH

shaunlebron 2017-06-09T15:25:55.666633Z

obviously that’s not an illustrative case for the problem we’re describing though

dominicm 2017-06-09T15:28:23.723679Z

I think the big benefit you get with

(-> 10
    distinct ;; This is like this because reasons of #1 XYZ, #2  DEH
    )
Is that it's clear you're targetting the distinct vs the the whole (->)

dominicm 2017-06-09T15:28:57.736580Z

The trailing paren hurts me though. I agree that it's an annoying edge case.

shaunlebron 2017-06-09T15:29:01.738062Z

(-> 10
    distinct
    ;; This is like this because reasons of #1 XYZ, #2  DEH
    (comment))

(-> 10
    distinct
    ;; This is like this because reasons of #1 XYZ, #2  DEH
    #_ignore_me!)

shaunlebron 2017-06-09T15:29:34.751016Z

it can be used as a sentinel maybe

dominicm 2017-06-09T15:29:39.752939Z

The answer is probably to do this:

(-> 10
     ;; This is like this because reasons of #1 XYZ, #2  DEH:
    distinct)

shaunlebron 2017-06-09T15:32:04.810049Z

that works, but (+ 1 2 (comment)) is 3, and I think that’s the only way to create a sentinel to allow Parinfer to keep the paren after a comment

shaunlebron 2017-06-09T15:33:11.835592Z

oh, and #__ would work too

dominicm 2017-06-09T15:33:41.847564Z

Not entirely great to be writing code specifically for parinfer though. My team don't use parinfer, so would probably ? over such code

shaunlebron 2017-06-09T15:35:33.890038Z

yeah I agree, was just tempted by the technical novelty of the solution i hadn’t realized before

1😝
dominicm 2017-06-09T17:37:03.406449Z

I have another codebase that can have the linter treatment btw, so let me know when trimming all works

shaunlebron 2017-06-09T19:43:37.896192Z

@dominicm trimming seems to work if you wanna give it a try

dominicm 2017-06-09T20:37:36.826721Z

@shaunlebron LGTM!

dominicm 2017-06-09T20:43:17.919590Z

just for fun, usage from vim: !aFparlinter --trim --stdin

dominicm 2017-06-09T20:47:21.985631Z

A case where using ;; Foo is like cause X: doesn't work:

{:foo 1
 ;;:bar 10
}

dominicm 2017-06-09T20:47:49.993263Z

again, uncertain how I feel about it 🙂 totally understand why it is how it is.

dominicm 2017-06-09T22:08:20.076361Z

@shaunlebron https://github.com/shaunlebron/parinfer/tree/master/lib#api > full text input The whole file? Does it have to be? Or can it be the top level form > cursorLine Relative to the section of text, or whole file?

shaunlebron 2017-06-09T22:09:07.084521Z

atom uses it to format top-level forms

shaunlebron 2017-06-09T22:09:23.087252Z

where the cursor is relative to the form

dominicm 2017-06-09T22:10:43.101163Z

Okay, cool. I think the nvim parinfer slow down may be due to it running on whole file. Currently hell on a 1.3k line file. Gonna try optimise the plugin 🙂

shaunlebron 2017-06-09T22:24:41.240551Z

@dominicm strange, not sure what the slowdown could be

shaunlebron 2017-06-09T22:25:37.249786Z

also, both zprint and cljfmt allow parens after a comment 😕