Skip to content

Commit

Permalink
Add support for post qualified import formatting (more cases) (#372)
Browse files Browse the repository at this point in the history
* Add support for post qualified import formatting.

Adds an option to use post qualified module imports.

Related to #284
Resolves #334

* Add failing test cases for post qualified import formatting.
  
Related to #284 and #334

* Fix imports test case 33 - 'qualified' goes before imported names

* Consolidate import module name logic

Co-authored-by: Jim McStanton <jim@jhmcstanton.com>
  • Loading branch information
akrmn and jhmcstanton authored Jul 16, 2021
1 parent d786187 commit 9c090d4
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 52 deletions.
24 changes: 14 additions & 10 deletions data/stylish-haskell.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -275,21 +275,25 @@ steps:
# Default: false
space_surround: false

# Enabling this argument will use the new GHC lib parse to format imports.
# Post qualify option moves any qualifies found in import declarations
# to the end of the declaration. This also adjust padding for any
# unqualified import declarations.
#
# This currently assumes a few things, it will assume that you want post
# qualified imports. It is also not as feature complete as the old
# imports formatting.
# - true: Qualified as <module name> is moved to the end of the
# declaration.
#
# It does not remove redundant lines or merge lines. As such, the full
# feature scope is still pending.
# > import Data.Bar
# > import Data.Foo qualified as F
#
# It _is_ however, a fine alternative if you are using features that are
# not parseable by haskell src extensions and you're comfortable with the
# presets.
# - false: Qualified remains in the default location and unqualified
# imports are padded to align with qualified imports.
#
# > import Data.Bar
# > import qualified Data.Foo as F
#
# Default: false
ghc_lib_parser: false
post_qualify: false


# Language pragmas
- language_pragmas:
Expand Down
1 change: 1 addition & 0 deletions lib/Language/Haskell/Stylish/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ parseImports config o = fmap (Imports.step columns) $ Imports.Options
<*> (o A..:? "list_padding" >>= maybe (pure $ def Imports.listPadding) parseListPadding)
<*> o A..:? "separate_lists" A..!= def Imports.separateLists
<*> o A..:? "space_surround" A..!= def Imports.spaceSurround
<*> o A..:? "post_qualify" A..!= def Imports.postQualified
where
def f = f Imports.defaultOptions

Expand Down
44 changes: 26 additions & 18 deletions lib/Language/Haskell/Stylish/Step/Imports.hs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ data Options = Options
, listPadding :: ListPadding
, separateLists :: Bool
, spaceSurround :: Bool
, postQualified :: Bool
} deriving (Eq, Show)

defaultOptions :: Options
Expand All @@ -73,6 +74,7 @@ defaultOptions = Options
, listPadding = LPConstant 4
, separateLists = True
, spaceSurround = False
, postQualified = False
}

data ListPadding
Expand Down Expand Up @@ -143,8 +145,8 @@ formatImports
-> NonEmpty (Located Import) -> Lines
formatImports maxCols options m moduleStats rawGroup =
runPrinter_ (PrinterConfig maxCols) [] m do
let
let

group
= NonEmpty.sortWith unLocated rawGroup
& mergeImports
Expand Down Expand Up @@ -177,25 +179,31 @@ printQualified Options{..} padNames stats (L _ decl) = do

when (isSafe decl) (putText "safe" >> space)

case (isQualified decl, isAnyQualified stats) of
(True, _) -> putText "qualified" >> space
(_, True) -> putText " " >> space
_ -> pure ()

moduleNamePosition <- length <$> getCurrentLine
forM_ (ideclPkgQual decl') $ \pkg -> putText (stringLiteral pkg) >> space
putText (moduleName decl)

-- Only print spaces if something follows.
when padNames $
when (isJust (ideclAs decl') || isHiding decl ||
not (null $ ideclHiding decl')) $
putText $
replicate (isLongestImport stats - importModuleNameLength decl) ' '
let
module_ = do
moduleNamePosition <- length <$> getCurrentLine
forM_ (ideclPkgQual decl') $ \pkg -> putText (stringLiteral pkg) >> space
putText (moduleName decl)
-- Only print spaces if something follows.
when padNames $
when (isJust (ideclAs decl') || isHiding decl ||
not (null $ ideclHiding decl')) $
putText $
replicate (isLongestImport stats - importModuleNameLength decl) ' '
pure moduleNamePosition

moduleNamePosition <-
case (postQualified, isQualified decl, isAnyQualified stats) of
(False, True , _ ) -> putText "qualified" *> space *> module_
(False, _ , True) -> putText " " *> space *> module_
(True , True , _ ) -> module_ <* space <* putText "qualified"
_ -> module_

beforeAliasPosition <- length <$> getCurrentLine
forM_ (ideclAs decl') \(L _ name) ->

forM_ (ideclAs decl') \(L _ name) -> do
space >> putText "as" >> space >> putText (moduleNameString name)

afterAliasPosition <- length <$> getCurrentLine

when (isHiding decl) (space >> putText "hiding")
Expand Down
Loading

0 comments on commit 9c090d4

Please sign in to comment.