Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Never fail to indent #21

Merged
merged 1 commit into from
Dec 10, 2024
Merged

Conversation

Hi-Angel
Copy link
Contributor

@Hi-Angel Hi-Angel commented Oct 2, 2024

A proper indentation engine should never look past the previous line. This is because a user frequently wants custom indentation, in all programming languages. A PureScript example:

f1 x = case x of
  true -> true
  _ -> false

f2 x = case x of
        true -> true
        _ -> false

So the proper behavior is: "take previous-line indentation, then if previous line has a modifier increase/decrease it". This is both simple, robust, typically meets the user expectations, and is AFAIK what all built-in major modes do.

Unfortunately we're long past that point, the purescript-mode indentation engine parses a lot of stuff it shouldn't. And frequently it gives a "parsing error". In my experience all those "errors" are bugs because the PS code is perfectly valid, but disregarding if it's a bug or an actual unfinished code in the buffer, engine should never leave a user with no indentation whatsoever.

So what this commit does is it detects such "errors", and takes previous indentation level. Even if it's not the correct indentation, in practice it's only off by purescript-indentation-left-offset, so a user often has much less to type compared to "no indentation" at all.


Now, it turns out the mode has another bug. As explained in the function being added, purescript-newline-and-indent calls indentation calculations on the wrong line. This isn't some special code that only purescript-newline-and-indent uses, it is a code that's being called by the TAB indentation as well.

As there are huge amounts of poorly documented code that shouldn't even be there in the first place, and are sometimes using local variables from other functions, I decided instead of trying to fix the code it would be more productive to just detect whether we're being called from purescript-newline-and-indent or not.

A proper indentation engine should never look past the previous line.
This is because a user frequently wants custom indentation, in all
programming languages. A PureScript example:

```haskell
f1 x = case x of
  true -> true
  _ -> false

f2 x = case x of
        true -> true
        _ -> false
```

So the proper behavior is: "take previous-line indentation, then if
previous line has a modifier increase/decrease it". This is both
simple, robust, typically meets the user expectations, and is AFAIK
what all built-in major modes do.

Unfortunately we're long past that point, the purescript-mode
indentation engine parses a lot of stuff it shouldn't. And frequently
it gives a "parsing error". In my experience all those "errors" are
bugs because the PS code is perfectly valid, but disregarding if it's
a bug or an actual unfinished code in the buffer, engine should never
leave a user with no indentation whatsoever.

So what this commit does is it detects such "errors", and takes
previous indentation level. Even if it's not the correct indentation,
in practice it's only off by `purescript-indentation-left-offset`, so
a user often has much less to type compared to "no indentation" at
all.

-------

Now, it turns out the mode has another bug. As explained in the
function being added, `purescript-newline-and-indent` calls
indentation calculations on the wrong line. This isn't some special
code that only `purescript-newline-and-indent` uses, it is a code
that's being called by the <kbd>TAB</kbd> indentation as well.

As there are huge amounts of poorly documented code that shouldn't
even be there in the first place, and are sometimes using local
variables from other functions, I decided instead of trying to fix the
code it would be more productive to just detect whether we're being
called from `purescript-newline-and-indent` or not.
@purcell
Copy link
Member

purcell commented Dec 9, 2024

I decided instead of trying to fix the code it would be more productive to just detect whether we're being called from purescript-newline-and-indent or not.

This is indeed a compromise, but perhaps a reasonable one, hard to say. I worry about adding an expedient hack when the underlying code is judged to be too hard to change though.

@Hi-Angel
Copy link
Contributor Author

Hi-Angel commented Dec 9, 2024

I decided instead of trying to fix the code it would be more productive to just detect whether we're being called from purescript-newline-and-indent or not.

This is indeed a compromise, but perhaps a reasonable one, hard to say. I worry about adding an expedient hack when the underlying code is judged to be too hard to change though.

Well, it doesn't seem like there are people actively developing the mode, so it is very likely if this change is unmerged, a better solution may not come at all.

I was thinking to dig more into indentation in this mode, but that depends on my spare time and other circumstances.

One thing I can definitely say is that this change immensely simplified working with the mode for me personally, because the older indentation code was pretty bad and was failing far too often with "parsing error" messages.

@purcell purcell merged commit 07e4d6e into purescript-emacs:master Dec 10, 2024
10 checks passed
@purcell
Copy link
Member

purcell commented Dec 10, 2024

Fair enough, let's merge and see how the wider user base gets on. :)

@purcell
Copy link
Member

purcell commented Dec 10, 2024

(The user base of a dozen people, that is 😉)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants