Ormolu can be turned on and off via the special comments:
{- ORMOLU_DISABLE -}
and
{- ORMOLU_ENABLE -}
This allows us to disable formatting selectively for code between these
markers or disable it for the entire file. To achieve the latter, just put
{- ORMOLU_DISABLE -} at the very top. Note that the source code should still
be parseable even without the “excluded” part. Because of that the magic
comments cannot be placed arbitrary, but should rather enclose independent
top-level definitions.
Closes#544.
It looks like when we call 'showSDocUnsafe' it uses `unsafeGlobalDynFlags`
wwhich the `settings` field is not initialised unless someone calls
`setUnsafeGlobalDynFlags`, `initGhcMonad` or `runGhc` and throws a panic.
I couldn't pinpoint the exact cause, but I suspect probably there was
a change either on Ormolu or ghc-lib-parser which removed a call to one
of the functions above before we print manualExts.
Anyway, we actually don't need to call `showSDocUnsafe` since we already
have a populated `DynFlags`. This commit removes the unsafe call and passes
the `DynFlags` we have to `showSDoc`.
It is tempting to enable ‘ImportQualifiedPost’ automatically for all files,
but in that case we won't be able to tell when to format in the
classical (prefix) style vs the new postfix style. Checking the list of
pragmas on per-file basis is not good enough because the extension can be
enabled in other ways, such as via the --ghc-opt flag.
GHC 8.10.1 comes with some changes to the AST, which works great for
Ormolu, but causes this commit to be a bit large:
* Trees That Grow extension points for new constructors are now statically
proven to be uninhabited, via noExtCon :: NoExtCon -> a. Thanks to this
change I got rid of many notImplemented calls.
* LPat constructor is now a lot more usable, so we don't need to use
the locatedPat combinator and can remove some boilerplate code.
Also it comes with ImportQualifiedPost and StandaloneKindSignatures
we should support. I did not implement them in this commit, they'll
be merged in later on.
It causes one behaviour change, where the ordering of qualified and
non-qualified imports of the same module is changed. This is due to
our usage of gcompare resulting a different ordering because of the
AST change caused by the ImportQualifiedPost extension. I think this is
acceptable and we shouldn't try to keep backwards compatibility there.
Another behaviour change is that previously HsExpr had a few extra
constructors for arrows and patterns used in expression context. Those
programs were syntactically incorrect, but refused on a later stage. But
we nonetheless formatted those constructs so Ormolu didn't fail there
while keeping the source code intact. However, now those constructors
are removed, so Ormolu fails with a parse error in this case (same as
GHC). I also removed some tests exhibiting this behaviour.
Preserve user-added newlines with the following normalizations:
* No newlines below where
* Consecutive newlines are compressed into a single newline
* Always surround documented declarations with blank lines
Previously we hanged record constructors but not record updates. It looks
like unlike other hanging constructions (lambdas, case expressions, and
do-blocks), record constructors and updates should rather be placed
normally. Indeed, when we stop hanging them, many constructions start to
look more reasonable and predictable (see the updated test cases).
Yet the change is not enough to fix the problem in general case: it is
enough to replace the record with a e.g. do-block to get the same failure.
To correct that we adjust what should fit in one line for hanging placement
to fire: now we consider the span between beginning of function and the
start of potentially-hanging construction.
This supports the two forms of ‘RecordDotSyntax’ that are likely to be
upstreamed ‘expr.lbl’ and ‘(.lbl)/ .lbl’.
We detect -fplugin=RecordDotPreprocessor and -pgmF=record-dot-preprocessor
in -o arguments or pragmas in files and just do the right thing.
[skip ci]
Before we sort of had two kinds of comments: with and without NOTEs. This is
confusing because there is really no difference between the two. I
originally added the words just because they are nicely highlighted in
Emacs, which, as I understand now, was not a good idea.