From 6888814f309f206d6b9860f3ae9b5e6c8525f17b Mon Sep 17 00:00:00 2001 From: Artyom Kazak Date: Mon, 24 Apr 2017 13:51:40 +0300 Subject: Take package imports into account when prettifying imports Fixes #106 --- lib/Language/Haskell/Stylish/Step/Imports.hs | 33 ++++++++++++++++------ .../Language/Haskell/Stylish/Step/Imports/Tests.hs | 27 ++++++++++++++++++ 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/lib/Language/Haskell/Stylish/Step/Imports.hs b/lib/Language/Haskell/Stylish/Step/Imports.hs index be60cba..78912d6 100644 --- a/lib/Language/Haskell/Stylish/Step/Imports.hs +++ b/lib/Language/Haskell/Stylish/Step/Imports.hs @@ -104,16 +104,33 @@ imports _ = [] importName :: H.ImportDecl l -> String importName i = let (H.ModuleName _ n) = H.importModule i in n +importPackage :: H.ImportDecl l -> Maybe String +importPackage i = H.importPkg i + + +-------------------------------------------------------------------------------- +-- | A "compound import name" is import's name and package (if present). For +-- instance, if you have an import @Foo.Bar@ from package @foobar@, the full +-- name will be @"foobar" Foo.Bar@. +compoundImportName :: H.ImportDecl l -> String +compoundImportName i = + case importPackage i of + Nothing -> importName i + Just pkg -> show pkg ++ " " ++ importName i + -------------------------------------------------------------------------------- longestImport :: [H.ImportDecl l] -> Int -longestImport = maximum . map (length . importName) +longestImport = maximum . map (length . compoundImportName) -------------------------------------------------------------------------------- -- | Compare imports for ordering compareImports :: H.ImportDecl l -> H.ImportDecl l -> Ordering -compareImports = comparing (map toLower . importName &&& H.importQualified) +compareImports = + comparing (map toLower . importName &&& + fmap (map toLower) . importPackage &&& + H.importQualified) -------------------------------------------------------------------------------- @@ -292,9 +309,9 @@ prettyImport columns Options{..} padQualified padName longest imp . withTail (", " ++)) ++ [")"]) - paddedBase = base $ padImport $ importName imp + paddedBase = base $ padImport $ compoundImportName imp - paddedNoSpecBase = base $ padImportNoSpec $ importName imp + paddedNoSpecBase = base $ padImportNoSpec $ compoundImportName imp padImport = if hasExtras && padName then padRight longest @@ -304,12 +321,11 @@ prettyImport columns Options{..} padQualified padName longest imp then padRight longest else id - base' baseName importAs hasHiding' = unwords $ concat $ filter (not . null) + base' baseName importAs hasHiding' = unwords $ concat $ [ ["import"] , source , safe , qualified - , show <$> maybeToList (H.importPkg imp) , [baseName] , importAs , hasHiding' @@ -319,9 +335,10 @@ prettyImport columns Options{..} padQualified padName longest imp ["as " ++ as | H.ModuleName _ as <- maybeToList $ H.importAs imp] ["hiding" | hasHiding] - inlineBaseLength = length $ base' (padImport $ importName imp) [] [] + inlineBaseLength = length $ + base' (padImport $ compoundImportName imp) [] [] - afterAliasBaseLength = length $ base' (padImport $ importName imp) + afterAliasBaseLength = length $ base' (padImport $ compoundImportName imp) ["as " ++ as | H.ModuleName _ as <- maybeToList $ H.importAs imp] [] (hasHiding, importSpecs) = case H.importSpecs imp of diff --git a/tests/Language/Haskell/Stylish/Step/Imports/Tests.hs b/tests/Language/Haskell/Stylish/Step/Imports/Tests.hs index e1a7462..02f7076 100644 --- a/tests/Language/Haskell/Stylish/Step/Imports/Tests.hs +++ b/tests/Language/Haskell/Stylish/Step/Imports/Tests.hs @@ -48,6 +48,7 @@ tests = testGroup "Language.Haskell.Stylish.Step.Imports.Tests" , testCase "case 19d" case19d , testCase "case 20" case20 , testCase "case 21" case21 + , testCase "case 22" case22 ] @@ -562,3 +563,29 @@ case21 = expected , "import X8 (type (+), (+))" , "import X9 hiding (x, y, z, x)" ] + +-------------------------------------------------------------------------------- +case22 :: Assertion +case22 = expected + @=? testStep (step 80 defaultOptions) input' + where + expected = unlines + [ "{-# LANGUAGE PackageImports #-}" + , "import A" + , "import \"blah\" A" + , "import \"foo\" A" + , "import qualified \"foo\" A as X" + , "import \"foo\" B (shortName, someLongName, someLongerName," + , " theLongestNameYet)" + ] + input' = unlines + [ "{-# LANGUAGE PackageImports #-}" + , "import A" + , "import \"foo\" A" + , "import \"blah\" A" + , "import qualified \"foo\" A as X" + -- this import fits into 80 chats without "foo", + -- but doesn't fit when "foo" is included into the calculation + , "import \"foo\" B (someLongName, someLongerName, " ++ + "theLongestNameYet, shortName)" + ] -- cgit v1.2.3