parinfer / parinfer.js

Let's simplify the way we write Lisp
https://shaunlebron.github.io/parinfer
MIT License
1.76k stars 40 forks source link

sibling alignment and tabStop integration in demo editor #150

Closed Engelberg closed 7 years ago

Engelberg commented 7 years ago
(defn foo
  "hello, this is a docstring"
  [a b]
  (my-function
    (+ 3 4)
    (- 1 2)))

Put the cursor in front of (+ 3 4) and delete the space between the end of my-function and (+ 3 4) in order to move that code up to the previous line.

The (- 1 2) code stays in its current indent position, which is wrong -- it should be aligned under the (+ 3 4). Worse, there's no way to easily get it into position by hitting tab. Tab moves the (- 1 2) block of code in small increments that don't have any underlying logic and it will either move too little or too much (changing the meaning of the code).

shaunlebron commented 7 years ago

So you want B instead of A below?

;; A
(defn foo
  "hello, this is a docstring"
  [a b]
  (my-function (+ 3 4)
    (- 1 2)))

;; B
(defn foo
  "hello, this is a docstring"
  [a b]
  (my-function (+ 3 4)
               (- 1 2)))

Parinfer does not enforce n-space indentation since some people (like david nolen actually) prefer two-space indentation everywhere.

And the tab issue is fixable since tabStops have been supported for a while (play here). I've forgotten to integrate it into the demo editor, so I'll do this. Thanks!

(defn foo
  "hello, this is a docstring"
  [a b]
  (my-function (+ 3 4)
^ ^            ^ tabStops
    |(- 1 2)))
Engelberg commented 7 years ago

For me, a common use case for paren mode is when arg1 is on the same line as the function, arg2 is directly under arg1, and then I edit the function name to be longer. It is important for arg2 to stay in line with arg1, which is where paren mode comes in handy. So if you're looking to get rid of paren mode, this would be a good use case to consider.

I understand the reasoning behind two spaces and could get used to that, but that's not the way most Clojure code is formatted and I want my code to match existing norms.

shaunlebron commented 7 years ago

You might be confusing the first example for the second. Lines only shift when their containing open-paren does.

(foo [bar
      baz]) ;; <-- shifts with `foo` since it is behind `[`

(foo bar
     baz)   ;; <-- does not shift with `foo`

About matching existing norms—Parinfer is intended to work with Racket/Hy/Clojure/Lisps without rocking the boat on formatting. It still works alongside more aggressive formatters (some notes here), but it isn't something that Parinfer should be doing itself since it has to stay tolerant of all styles that comply with its inference invariants.

shaunlebron commented 7 years ago

Having said this, I'll look at sticky alignment here as a possible option: https://github.com/shaunlebron/parinfer/issues/151

shaunlebron commented 7 years ago

@Engelberg I added better tabbing to Parinfer which can you play with in the improved demo editor now. Thanks for your feedback