on master help sign in
Put operators after other names

Previously ‘RdrName’s were sorted by simple comparison of their names. However, in ASCII not all “operator-like” symbols go after alpha-numeric characters. This resulted in this sort of output: import Linear.Vector ((*^), Additive (..), (^*)) The new ordering scheme allows us to separate operators and other names: import Linear.Vector (Additive (..), (*^), (^*))

commit2b1d013d7ca6f5af434d7d828846328fbf07bae6 authorMark Karpov <markkarpov92@gmail.com> dateWed 3 Jun 2020, 17:23 (6 years ago) parent67e43e0
10 files changed+41−19
CHANGELOG.md+3 data/examples/import/explicit-imports-out.hs+4−4 data/examples/import/explicit-imports-with-comments-out.hs+3−2 data/examples/import/nested-explicit-imports-out.hs+6−6 data/examples/import/qualified-prelude-out.hs+1−1 data/examples/import/sorted-export-list-out.hs+1 data/examples/import/sorted-export-list.hs+1 src/Ormolu/Imports.hs+20−4 src/Ormolu/Printer/Meat/Declaration.hs+1−1 src/Ormolu/Printer/Meat/Declaration/Value.hs+1−1
CHANGELOG.md+3
@@ -7,6 +7,9 @@
77 disabled part is still syntactically correct. [Issue
88 601](https://github.com/tweag/ormolu/issues/601).
99
10+* Improved sorting of operators in imports. [Issue
11+ 602](https://github.com/tweag/ormolu/issues/602).
12+
1013## Ormolu 0.1.0.0
1114
1215* Fixed rendering of type signatures concerning several identifiers. [Issue
data/examples/import/explicit-imports-out.hs+4−4
@@ -1,12 +1,12 @@
11import qualified MegaModule as M
2− ( (<<<),
3− (>>>),
4− Either,
2+ ( Either,
53 Maybe (Just, Nothing),
64 MaybeT (..),
7− Monad ((>>), (>>=), return),
5+ Monad (return, (>>), (>>=)),
86 MonadBaseControl,
97 join,
108 liftIO,
119 void,
10+ (<<<),
11+ (>>>),
1212 )
data/examples/import/explicit-imports-with-comments-out.hs+3−2
@@ -1,6 +1,7 @@
11import qualified MegaModule as M
22 ( -- (1)
3− (<<<), -- (2)
4− (>>>),
3+ -- (2)
54 Either, -- (3)
5+ (<<<),
6+ (>>>),
67 )
data/examples/import/nested-explicit-imports-out.hs+6−6
@@ -1,10 +1,10 @@
11import qualified MegaModule as M
2− ( (<<<),
3− (>>>),
4− Either,
2+ ( Either,
53 Monad
6− ( (>>),
7− (>>=),
8− return
4+ ( return,
5+ (>>),
6+ (>>=)
97 ),
8+ (<<<),
9+ (>>>),
1010 )
data/examples/import/qualified-prelude-out.hs+1−1
@@ -1,4 +1,4 @@
11module P where
22
33import qualified Prelude
4−import Prelude hiding ((.), id)
4+import Prelude hiding (id, (.))
data/examples/import/sorted-export-list-out.hsnew file+1
@@ -0,0 +1 @@
1+import Linear.Vector (Additive (..), (*^), (^*))
data/examples/import/sorted-export-list.hsnew file+1
@@ -0,0 +1 @@
1+import Linear.Vector (Additive (..), (*^), (^*))
src/Ormolu/Imports.hs+20−4
@@ -9,13 +9,14 @@ module Ormolu.Imports
99where
1010
1111import Data.Bifunctor
12+import Data.Char (isAlphaNum)
1213import Data.Function (on)
1314import Data.Generics (gcompare)
1415import Data.List (nubBy, sortBy)
1516import GHC hiding (GhcPs, IE)
1617import GHC.Hs.Extension
1718import GHC.Hs.ImpExp (IE (..))
18−import Ormolu.Utils (notImplemented)
19+import Ormolu.Utils (notImplemented, showOutputable)
1920
2021-- | Sort imports by module name. This also sorts explicit import lists for
2122-- each declaration.
@@ -77,12 +78,27 @@ getIewn = \case
7778
7879-- | Compare two @'IEWrapppedName' 'RdrName'@ things.
7980compareIewn :: IEWrappedName RdrName -> IEWrappedName RdrName -> Ordering
80−compareIewn (IEName x) (IEName y) = unLoc x `compare` unLoc y
81+compareIewn (IEName x) (IEName y) = unLoc x `compareRdrName` unLoc y
8182compareIewn (IEName _) (IEPattern _) = LT
8283compareIewn (IEName _) (IEType _) = LT
8384compareIewn (IEPattern _) (IEName _) = GT
84−compareIewn (IEPattern x) (IEPattern y) = unLoc x `compare` unLoc y
85+compareIewn (IEPattern x) (IEPattern y) = unLoc x `compareRdrName` unLoc y
8586compareIewn (IEPattern _) (IEType _) = LT
8687compareIewn (IEType _) (IEName _) = GT
8788compareIewn (IEType _) (IEPattern _) = GT
88−compareIewn (IEType x) (IEType y) = unLoc x `compare` unLoc y
89+compareIewn (IEType x) (IEType y) = unLoc x `compareRdrName` unLoc y
90+
91+compareRdrName :: RdrName -> RdrName -> Ordering
92+compareRdrName x y =
93+ case (getNameStr x, getNameStr y) of
94+ ([], []) -> EQ
95+ ((_ : _), []) -> GT
96+ ([], (_ : _)) -> LT
97+ ((x' : _), (y' : _)) ->
98+ case (isAlphaNum x', isAlphaNum y') of
99+ (False, False) -> x `compare` y
100+ (True, False) -> LT
101+ (False, True) -> GT
102+ (True, True) -> x `compare` y
103+ where
104+ getNameStr = showOutputable . rdrNameOcc
src/Ormolu/Printer/Meat/Declaration.hs+1−1
@@ -12,7 +12,7 @@ module Ormolu.Printer.Meat.Declaration
1212where
1313
1414import Data.List (sort)
15−import Data.List.NonEmpty ((<|), NonEmpty (..))
15+import Data.List.NonEmpty (NonEmpty (..), (<|))
1616import qualified Data.List.NonEmpty as NE
1717import GHC hiding (InlinePragma)
1818import OccName (occNameFS)
src/Ormolu/Printer/Meat/Declaration/Value.hs+1−1
@@ -21,7 +21,7 @@ import Data.Char (isPunctuation, isSymbol)
2121import Data.Data hiding (Infix, Prefix)
2222import Data.Functor ((<&>))
2323import Data.List (intersperse, sortOn)
24−import Data.List.NonEmpty ((<|), NonEmpty (..))
24+import Data.List.NonEmpty (NonEmpty (..), (<|))
2525import qualified Data.List.NonEmpty as NE
2626import Data.Text (Text)
2727import qualified Data.Text as Text