summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2017-07-05 08:07:21 +0100
committerSean Whitton <spwhitton@spwhitton.name>2017-07-05 08:07:21 +0100
commitccf99d542eb2149a4037a6483b9d63b5ba0fc191 (patch)
tree1b0ad9676fec43076012c84f1fb73a5fc2606ee0
parenteb701be3473ecd02f21c24614a4773162024930a (diff)
parent6df99cb50b5292c578d7c96f5753749b9d938b72 (diff)
downloadstylish-haskell-ccf99d542eb2149a4037a6483b9d63b5ba0fc191.tar.gz
Merge tag '0.7.1.0'
0.7.1.0
-rw-r--r--.travis.yml5
-rw-r--r--CHANGELOG27
-rw-r--r--README.markdown11
-rw-r--r--data/stylish-haskell.yaml20
-rw-r--r--lib/Language/Haskell/Stylish.hs5
-rw-r--r--lib/Language/Haskell/Stylish/Align.hs3
-rw-r--r--lib/Language/Haskell/Stylish/Block.hs6
-rw-r--r--lib/Language/Haskell/Stylish/Config.hs20
-rw-r--r--lib/Language/Haskell/Stylish/Parse.hs7
-rw-r--r--lib/Language/Haskell/Stylish/Step.hs2
-rw-r--r--lib/Language/Haskell/Stylish/Step/Imports.hs114
-rw-r--r--lib/Language/Haskell/Stylish/Step/LanguagePragmas.hs10
-rw-r--r--lib/Language/Haskell/Stylish/Step/SimpleAlign.hs2
-rw-r--r--lib/Language/Haskell/Stylish/Step/UnicodeSyntax.hs11
-rw-r--r--lib/Language/Haskell/Stylish/Util.hs21
-rw-r--r--src/Main.hs5
-rw-r--r--stack.yaml8
-rw-r--r--stylish-haskell.cabal40
-rw-r--r--tests/Language/Haskell/Stylish/Parse/Tests.hs6
-rw-r--r--tests/Language/Haskell/Stylish/Step/Imports/Tests.hs123
20 files changed, 338 insertions, 108 deletions
diff --git a/.travis.yml b/.travis.yml
index eeb0184..5e5c816 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -7,13 +7,10 @@ cache:
addons:
apt:
- sources:
- - hvr-ghc
packages:
- - ghc-7.10.3
+ - libgmp-dev
before_install:
-- export PATH=/opt/ghc/7.10.3/bin:$PATH
- mkdir -p ~/.local/bin
- export PATH=$HOME/.local/bin:$PATH
- travis_retry curl -L https://www.stackage.org/stack/linux-x86_64 | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack'
diff --git a/CHANGELOG b/CHANGELOG
index 3bb69bc..0d4d986 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,32 @@
# CHANGELOG
+- 0.7.1.0
+ * Keep `safe` and `{-# SOURCE #-}` import annotations (by Moritz Drexl)
+
+- 0.7.0.0
+ * If there's parse errors, show these and exit with code 1
+ * Bump `aeson` to 1.1
+ * Bump `directory` to 1.3
+ * Bump `haskell-src-exts` to 1.19
+
+- 0.6.5.0
+ * Fix issue with unit records (by Mizunashi Mana)
+ * Bump `HUnit` to 1.5
+
+- 0.6.4.0
+ * Remove `XmlSyntax` from whitelisted language extensions, since it was
+ causing parsing errors
+
+- 0.6.3.0
+ * Bump `optparse-applicative` to 0.13.0.0
+ * Export Import options & add a default
+ * Add `list_padding: module_name` option (by Oleg Grenrus)
+ * Bump `aeson` to 1.0 (by Oleg Grenrus)
+ * Special setting for empty import lists (by Oleg Grenrus)
+
+- 0.6.2.0
+ * Bump `haskell-src-exts` to 1.18
+
- 0.6.1.0
* Fix line patching issue in Editor
diff --git a/README.markdown b/README.markdown
index 01f20d9..d271b4c 100644
--- a/README.markdown
+++ b/README.markdown
@@ -90,11 +90,18 @@ VIM integration
---------------
Since it works as a filter it is pretty easy to integrate this with VIM.
-Just call
+
+You can call
:%!stylish-haskell
-or add a keybinding for it.
+and add a keybinding for it.
+
+Or you can define `formatprg`
+
+ :set formatprg=stylish-haskell
+
+and then use `gq`.
There is also the [vim-stylish-haskell] plugin, which runs stylish-haskell
automatically when you save a Haskell file.
diff --git a/data/stylish-haskell.yaml b/data/stylish-haskell.yaml
index 2398e6b..3bed473 100644
--- a/data/stylish-haskell.yaml
+++ b/data/stylish-haskell.yaml
@@ -87,8 +87,26 @@ steps:
# Default: inline
long_list_align: inline
+ # Align empty list (importing instances)
+ #
+ # Empty list align has following options
+ #
+ # - inherit: inherit list_align setting
+ #
+ # - right_after: () is right after the module name:
+ #
+ # > import Vector.Instances ()
+ #
+ # Default: inherit
+ empty_list_align: inherit
+
# List padding determines indentation of import list on lines after import.
- # This option affects 'list_align' and 'long_list_align'.
+ # This option affects 'long_list_align'.
+ #
+ # - <integer>: constant value
+ #
+ # - module_name: align under start of module name.
+ # Useful for 'file' and 'group' align settings.
list_padding: 4
# Separate lists option affects formating of import list for type
diff --git a/lib/Language/Haskell/Stylish.hs b/lib/Language/Haskell/Stylish.hs
index 5b1e918..46543ec 100644
--- a/lib/Language/Haskell/Stylish.hs
+++ b/lib/Language/Haskell/Stylish.hs
@@ -9,9 +9,6 @@ module Language.Haskell.Stylish
, tabs
, trailingWhitespace
, unicodeSyntax
- -- ** Data types
- , Imports.Align (..)
- , LanguagePragmas.Style (..)
-- ** Helpers
, stepName
-- * Config
@@ -51,7 +48,7 @@ simpleAlign = SimpleAlign.step
--------------------------------------------------------------------------------
imports :: Int -- ^ columns
- -> Imports.Align
+ -> Imports.Options
-> Step
imports = Imports.step
diff --git a/lib/Language/Haskell/Stylish/Align.hs b/lib/Language/Haskell/Stylish/Align.hs
index c58b133..8e6665f 100644
--- a/lib/Language/Haskell/Stylish/Align.hs
+++ b/lib/Language/Haskell/Stylish/Align.hs
@@ -9,7 +9,7 @@ module Language.Haskell.Stylish.Align
--------------------------------------------------------------------------------
import Data.Char (isSpace)
import Data.List (nub)
-import qualified Language.Haskell.Exts.Annotated as H
+import qualified Language.Haskell.Exts as H
--------------------------------------------------------------------------------
@@ -59,6 +59,7 @@ align
:: Int -- ^ Max columns
-> [Alignable H.SrcSpan] -- ^ Alignables
-> [Change String] -- ^ Changes performing the alignment.
+align _ [] = []
align maxColumns alignment
-- Do not make any change if we would go past the maximum number of columns.
| longestLeft + longestRight > maxColumns = []
diff --git a/lib/Language/Haskell/Stylish/Block.hs b/lib/Language/Haskell/Stylish/Block.hs
index d4cca7d..46111ee 100644
--- a/lib/Language/Haskell/Stylish/Block.hs
+++ b/lib/Language/Haskell/Stylish/Block.hs
@@ -15,9 +15,9 @@ module Language.Haskell.Stylish.Block
--------------------------------------------------------------------------------
-import Control.Arrow (arr, (&&&), (>>>))
-import qualified Data.IntSet as IS
-import qualified Language.Haskell.Exts.Annotated as H
+import Control.Arrow (arr, (&&&), (>>>))
+import qualified Data.IntSet as IS
+import qualified Language.Haskell.Exts as H
--------------------------------------------------------------------------------
diff --git a/lib/Language/Haskell/Stylish/Config.hs b/lib/Language/Haskell/Stylish/Config.hs
index d14e1be..b83cf3a 100644
--- a/lib/Language/Haskell/Stylish/Config.hs
+++ b/lib/Language/Haskell/Stylish/Config.hs
@@ -181,15 +181,19 @@ parseSimpleAlign c o = SimpleAlign.step
parseImports :: Config -> A.Object -> A.Parser Step
parseImports config o = Imports.step
<$> pure (configColumns config)
- <*> (Imports.Align
- <$> (o A..:? "align" >>= parseEnum aligns Imports.Global)
- <*> (o A..:? "list_align" >>= parseEnum listAligns Imports.AfterAlias)
+ <*> (Imports.Options
+ <$> (o A..:? "align" >>= parseEnum aligns (def Imports.importAlign))
+ <*> (o A..:? "list_align" >>= parseEnum listAligns (def Imports.listAlign))
<*> (o A..:? "long_list_align"
- >>= parseEnum longListAligns Imports.Inline)
+ >>= parseEnum longListAligns (def Imports.longListAlign))
-- Note that padding has to be at least 1. Default is 4.
- <*> (maybe 4 (max 1) <$> o A..:? "list_padding")
- <*> o A..:? "separate_lists" A..!= True)
+ <*> (o A..:? "empty_list_align"
+ >>= parseEnum emptyListAligns (def Imports.emptyListAlign))
+ <*> o A..:? "list_padding" A..!= (def Imports.listPadding)
+ <*> o A..:? "separate_lists" A..!= (def Imports.separateLists))
where
+ def f = f Imports.defaultOptions
+
aligns =
[ ("global", Imports.Global)
, ("file", Imports.File)
@@ -210,6 +214,10 @@ parseImports config o = Imports.step
, ("multiline", Imports.Multiline)
]
+ emptyListAligns =
+ [ ("inherit", Imports.Inherit)
+ , ("right_after", Imports.RightAfter)
+ ]
--------------------------------------------------------------------------------
parseLanguagePragmas :: Config -> A.Object -> A.Parser Step
diff --git a/lib/Language/Haskell/Stylish/Parse.hs b/lib/Language/Haskell/Stylish/Parse.hs
index 2b16b30..596bccb 100644
--- a/lib/Language/Haskell/Stylish/Parse.hs
+++ b/lib/Language/Haskell/Stylish/Parse.hs
@@ -5,14 +5,16 @@ module Language.Haskell.Stylish.Parse
--------------------------------------------------------------------------------
+import Data.List (isPrefixOf, nub)
import Data.Maybe (fromMaybe, listToMaybe)
-import qualified Language.Haskell.Exts.Annotated as H
-import Data.List (isPrefixOf, nub)
+import qualified Language.Haskell.Exts as H
+
--------------------------------------------------------------------------------
import Language.Haskell.Stylish.Config
import Language.Haskell.Stylish.Step
+
--------------------------------------------------------------------------------
-- | Syntax-related language extensions are always enabled for parsing. Since we
-- can't authoritatively know which extensions are enabled at compile-time, we
@@ -27,7 +29,6 @@ defaultExtensions = map H.EnableExtension
, H.PatternGuards
, H.StandaloneDeriving
, H.UnicodeSyntax
- , H.XmlSyntax
]
diff --git a/lib/Language/Haskell/Stylish/Step.hs b/lib/Language/Haskell/Stylish/Step.hs
index f053f8b..e5f3424 100644
--- a/lib/Language/Haskell/Stylish/Step.hs
+++ b/lib/Language/Haskell/Stylish/Step.hs
@@ -8,7 +8,7 @@ module Language.Haskell.Stylish.Step
--------------------------------------------------------------------------------
-import qualified Language.Haskell.Exts.Annotated as H
+import qualified Language.Haskell.Exts as H
--------------------------------------------------------------------------------
diff --git a/lib/Language/Haskell/Stylish/Step/Imports.hs b/lib/Language/Haskell/Stylish/Step/Imports.hs
index 82ba96f..29b8cc2 100644
--- a/lib/Language/Haskell/Stylish/Step/Imports.hs
+++ b/lib/Language/Haskell/Stylish/Step/Imports.hs
@@ -1,21 +1,28 @@
{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE OverloadedStrings #-}
--------------------------------------------------------------------------------
module Language.Haskell.Stylish.Step.Imports
- ( Align (..)
+ ( Options (..)
+ , defaultOptions
, ImportAlign (..)
, ListAlign (..)
, LongListAlign (..)
+ , EmptyListAlign (..)
+ , ListPadding (..)
, step
) where
--------------------------------------------------------------------------------
import Control.Arrow ((&&&))
+import Control.Monad (void)
import Data.Char (toLower)
import Data.List (intercalate, sortBy)
import Data.Maybe (isJust, maybeToList)
import Data.Ord (comparing)
-import qualified Language.Haskell.Exts.Annotated as H
+import qualified Language.Haskell.Exts as H
+import qualified Data.Aeson as A
+import qualified Data.Aeson.Types as A
--------------------------------------------------------------------------------
@@ -25,13 +32,28 @@ import Language.Haskell.Stylish.Step
import Language.Haskell.Stylish.Util
--------------------------------------------------------------------------------
-data Align = Align
- { importAlign :: ImportAlign
- , listAlign :: ListAlign
- , longListAlign :: LongListAlign
- , listPadding :: Int
- , separateLists :: Bool
+data Options = Options
+ { importAlign :: ImportAlign
+ , listAlign :: ListAlign
+ , longListAlign :: LongListAlign
+ , emptyListAlign :: EmptyListAlign
+ , listPadding :: ListPadding
+ , separateLists :: Bool
+ } deriving (Eq, Show)
+
+defaultOptions :: Options
+defaultOptions = Options
+ { importAlign = Global
+ , listAlign = AfterAlias
+ , longListAlign = Inline
+ , emptyListAlign = Inherit
+ , listPadding = LPConstant 4
+ , separateLists = True
}
+
+data ListPadding
+ = LPConstant Int
+ | LPModuleName
deriving (Eq, Show)
data ImportAlign
@@ -47,6 +69,11 @@ data ListAlign
| AfterAlias
deriving (Eq, Show)
+data EmptyListAlign
+ = Inherit
+ | RightAfter
+ deriving (Eq, Show)
+
data LongListAlign
= Inline
| InlineWithBreak
@@ -83,8 +110,8 @@ compareImportSpecs :: H.ImportSpec l -> H.ImportSpec l -> Ordering
compareImportSpecs = comparing key
where
key :: H.ImportSpec l -> (Int, Bool, String)
- key (H.IVar _ x) = (1, isOperator x, nameToString x)
- key (H.IAbs _ _ x) = (0, False, nameToString x)
+ key (H.IVar _ x) = (1, isOperator x, nameToString x)
+ key (H.IAbs _ _ x) = (0, False, nameToString x)
key (H.IThingAll _ x) = (0, False, nameToString x)
key (H.IThingWith _ x _) = (0, False, nameToString x)
@@ -135,14 +162,22 @@ prettyImportSpec separate = prettyImportSpec'
--------------------------------------------------------------------------------
prettyImport :: (Ord l, Show l) =>
- Int -> Align -> Bool -> Bool -> Int -> H.ImportDecl l -> [String]
-prettyImport columns Align{..} padQualified padName longest imp =
- case longListAlign of
- Inline -> inlineWrap
- InlineWithBreak -> longListWrapper inlineWrap inlineWithBreakWrap
+ Int -> Options -> Bool -> Bool -> Int -> H.ImportDecl l -> [String]
+prettyImport columns Options{..} padQualified padName longest imp
+ | (void `fmap` H.importSpecs imp) == emptyImportSpec = emptyWrap
+ | otherwise = case longListAlign of
+ Inline -> inlineWrap
+ InlineWithBreak -> longListWrapper inlineWrap inlineWithBreakWrap
InlineToMultiline -> longListWrapper inlineWrap inlineToMultilineWrap
- Multiline -> longListWrapper inlineWrap multilineWrap
+ Multiline -> longListWrapper inlineWrap multilineWrap
where
+ emptyImportSpec = Just (H.ImportSpecList () False [])
+ -- "import" + space + qualifiedLength has space in it.
+ listPadding' = listPaddingValue (6 + 1 + qualifiedLength) listPadding
+ where
+ qualifiedLength =
+ if null qualified then 0 else 1 + sum (map length qualified)
+
longListWrapper shortWrap longWrap
| listAlign == NewLine
|| length shortWrap > 1
@@ -150,6 +185,10 @@ prettyImport columns Align{..} padQualified padName longest imp =
= longWrap
| otherwise = shortWrap
+ emptyWrap = case emptyListAlign of
+ Inherit -> inlineWrap
+ RightAfter -> [paddedNoSpecBase ++ " ()"]
+
inlineWrap = inlineWrapper
$ mapSpecs
$ withInit (++ ",")
@@ -157,13 +196,13 @@ prettyImport columns Align{..} padQualified padName longest imp =
. withLast (++ ")")
inlineWrapper = case listAlign of
- NewLine -> (paddedNoSpecBase :) . wrapRest columns listPadding
+ NewLine -> (paddedNoSpecBase :) . wrapRest columns listPadding'
WithAlias -> wrap columns paddedBase (inlineBaseLength + 1)
-- Add 1 extra space to ensure same padding as in original code.
AfterAlias -> withTail (' ' :)
. wrap columns paddedBase (afterAliasBaseLength + 1)
- inlineWithBreakWrap = paddedNoSpecBase : wrapRest columns listPadding
+ inlineWithBreakWrap = paddedNoSpecBase : wrapRest columns listPadding'
( mapSpecs
$ withInit (++ ",")
. withHead ("(" ++)
@@ -176,7 +215,7 @@ prettyImport columns Align{..} padQualified padName longest imp =
| otherwise = inlineWithBreakWrap
-- 'wrapRest 0' ensures that every item of spec list is on new line.
- multilineWrap = paddedNoSpecBase : wrapRest 0 listPadding
+ multilineWrap = paddedNoSpecBase : wrapRest 0 listPadding'
( mapSpecs
( withHead ("( " ++)
. withTail (", " ++))
@@ -196,6 +235,8 @@ prettyImport columns Align{..} padQualified padName longest imp =
base' baseName importAs hasHiding' = unwords $ concat $ filter (not . null)
[ ["import"]
+ , source
+ , safe
, qualified
, show <$> maybeToList (H.importPkg imp)
, [baseName]
@@ -220,9 +261,22 @@ prettyImport columns Align{..} padQualified padName longest imp =
qualified
| H.importQualified imp = ["qualified"]
- | padQualified = [" "]
+ | padQualified =
+ if H.importSrc imp
+ then []
+ else if H.importSafe imp
+ then [" "]
+ else [" "]
| otherwise = []
+ safe
+ | H.importSafe imp = ["safe"]
+ | otherwise = []
+
+ source
+ | H.importSrc imp = ["{-# SOURCE #-}"]
+ | otherwise = []
+
mapSpecs f = case importSpecs of
Nothing -> [] -- Import everything
Just [] -> ["()"] -- Instance only imports
@@ -230,7 +284,7 @@ prettyImport columns Align{..} padQualified padName longest imp =
--------------------------------------------------------------------------------
-prettyImportGroup :: Int -> Align -> Bool -> Int
+prettyImportGroup :: Int -> Options -> Bool -> Int
-> [H.ImportDecl LineBlock]
-> Lines
prettyImportGroup columns align fileAlign longest imps =
@@ -253,12 +307,12 @@ prettyImportGroup columns align fileAlign longest imps =
--------------------------------------------------------------------------------
-step :: Int -> Align -> Step
+step :: Int -> Options -> Step
step columns = makeStep "Imports" . step' columns
--------------------------------------------------------------------------------
-step' :: Int -> Align -> Lines -> Module -> Lines
+step' :: Int -> Options -> Lines -> Module -> Lines
step' columns align ls (module', _) = applyChanges
[ change block $ const $
prettyImportGroup columns align fileAlign longest importGroup
@@ -273,3 +327,17 @@ step' columns align ls (module', _) = applyChanges
fileAlign = case importAlign align of
File -> any H.importQualified imps
_ -> False
+
+--------------------------------------------------------------------------------
+listPaddingValue :: Int -> ListPadding -> Int
+listPaddingValue _ (LPConstant n) = n
+listPaddingValue n LPModuleName = n
+
+--------------------------------------------------------------------------------
+
+instance A.FromJSON ListPadding where
+ parseJSON (A.String "module_name") = return LPModuleName
+ parseJSON (A.Number n) | n' >= 1 = return $ LPConstant n'
+ where
+ n' = truncate n
+ parseJSON v = A.typeMismatch "'module_name' or >=1 number" v
diff --git a/lib/Language/Haskell/Stylish/Step/LanguagePragmas.hs b/lib/Language/Haskell/Stylish/Step/LanguagePragmas.hs
index 0239736..c63d90a 100644
--- a/lib/Language/Haskell/Stylish/Step/LanguagePragmas.hs
+++ b/lib/Language/Haskell/Stylish/Step/LanguagePragmas.hs
@@ -10,14 +10,14 @@ module Language.Haskell.Stylish.Step.LanguagePragmas
--------------------------------------------------------------------------------
import qualified Data.Set as S
-import qualified Language.Haskell.Exts.Annotated as H
+import qualified Language.Haskell.Exts as H
--------------------------------------------------------------------------------
-import Language.Haskell.Stylish.Block
-import Language.Haskell.Stylish.Editor
-import Language.Haskell.Stylish.Step
-import Language.Haskell.Stylish.Util
+import Language.Haskell.Stylish.Block
+import Language.Haskell.Stylish.Editor
+import Language.Haskell.Stylish.Step
+import Language.Haskell.Stylish.Util
--------------------------------------------------------------------------------
diff --git a/lib/Language/Haskell/Stylish/Step/SimpleAlign.hs b/lib/Language/Haskell/Stylish/Step/SimpleAlign.hs
index c89e8a1..c83c482 100644
--- a/lib/Language/Haskell/Stylish/Step/SimpleAlign.hs
+++ b/lib/Language/Haskell/Stylish/Step/SimpleAlign.hs
@@ -9,7 +9,7 @@ module Language.Haskell.Stylish.Step.SimpleAlign
--------------------------------------------------------------------------------
import Data.Data (Data)
import Data.Maybe (maybeToList)
-import qualified Language.Haskell.Exts.Annotated as H
+import qualified Language.Haskell.Exts as H
--------------------------------------------------------------------------------
diff --git a/lib/Language/Haskell/Stylish/Step/UnicodeSyntax.hs b/lib/Language/Haskell/Stylish/Step/UnicodeSyntax.hs
index 0a4438a..01e29e8 100644
--- a/lib/Language/Haskell/Stylish/Step/UnicodeSyntax.hs
+++ b/lib/Language/Haskell/Stylish/Step/UnicodeSyntax.hs
@@ -5,11 +5,12 @@ module Language.Haskell.Stylish.Step.UnicodeSyntax
--------------------------------------------------------------------------------
-import Data.List (isPrefixOf, sort)
-import Data.Map (Map)
-import qualified Data.Map as M
-import Data.Maybe (maybeToList)
-import qualified Language.Haskell.Exts.Annotated as H
+import Data.List (isPrefixOf,
+ sort)
+import Data.Map (Map)
+import qualified Data.Map as M
+import Data.Maybe (maybeToList)
+import qualified Language.Haskell.Exts as H
--------------------------------------------------------------------------------
diff --git a/lib/Language/Haskell/Stylish/Util.hs b/lib/Language/Haskell/Stylish/Util.hs
index ed5de91..54abef5 100644
--- a/lib/Language/Haskell/Stylish/Util.hs
+++ b/lib/Language/Haskell/Stylish/Util.hs
@@ -17,13 +17,14 @@ module Language.Haskell.Stylish.Util
--------------------------------------------------------------------------------
-import Control.Arrow ((&&&), (>>>))
-import Data.Char (isAlpha)
-import Data.Data (Data)
-import qualified Data.Generics as G
-import Data.Maybe (fromMaybe, listToMaybe, maybeToList)
-import Data.Typeable (cast)
-import qualified Language.Haskell.Exts.Annotated as H
+import Control.Arrow ((&&&), (>>>))
+import Data.Char (isAlpha)
+import Data.Data (Data)
+import qualified Data.Generics as G
+import Data.Maybe (fromMaybe, listToMaybe,
+ maybeToList)
+import Data.Typeable (cast)
+import qualified Language.Haskell.Exts as H
--------------------------------------------------------------------------------
@@ -112,17 +113,17 @@ withHead f (x : xs) = f x : xs
--------------------------------------------------------------------------------
withLast :: (a -> a) -> [a] -> [a]
withLast _ [] = []
-withLast f [x] = [f x]
+withLast f [x] = [f x]
withLast f (x : xs) = x : withLast f xs
--------------------------------------------------------------------------------
withInit :: (a -> a) -> [a] -> [a]
withInit _ [] = []
-withInit _ [x] = [x]
+withInit _ [x] = [x]
withInit f (x : xs) = f x : withInit f xs
--------------------------------------------------------------------------------
withTail :: (a -> a) -> [a] -> [a]
-withTail _ [] = []
+withTail _ [] = []
withTail f (x : xs) = x : map f xs
diff --git a/src/Main.hs b/src/Main.hs
index d481517..8eeb7ab 100644
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -10,6 +10,7 @@ import Data.Monoid ((<>))
import Data.Version (showVersion)
import qualified Options.Applicative as OA
import qualified Paths_stylish_haskell
+import System.Exit (exitFailure)
import qualified System.IO as IO
import qualified System.IO.Strict as IO.Strict
@@ -117,8 +118,10 @@ file sa conf mfp = do
let result = runSteps (configLanguageExtensions conf)
mfp (configSteps conf) $ lines contents
case result of
- Left err -> IO.hPutStrLn IO.stderr err >> write contents contents
Right ok -> write contents $ unlines ok
+ Left err -> do
+ IO.hPutStrLn IO.stderr err
+ exitFailure
where
write old new = case mfp of
Nothing -> putStrNewline new
diff --git a/stack.yaml b/stack.yaml
index f8a01a5..8f26efa 100644
--- a/stack.yaml
+++ b/stack.yaml
@@ -1,5 +1,9 @@
flags: {}
packages:
- '.'
-extra-deps: []
-resolver: lts-5.0
+extra-deps:
+- 'haskell-src-exts-1.18.2'
+- 'optparse-applicative-0.13.0.0'
+resolver: lts-6.10
+install-ghc: true
+system-ghc: false
diff --git a/stylish-haskell.cabal b/stylish-haskell.cabal
index 2c4ee95..e8e6bb7 100644
--- a/stylish-haskell.cabal
+++ b/stylish-haskell.cabal
@@ -1,5 +1,5 @@
Name: stylish-haskell
-Version: 0.6.1.0
+Version: 0.7.1.0
Synopsis: Haskell code prettifier
Homepage: https://github.com/jaspervdj/stylish-haskell
License: BSD3
@@ -25,10 +25,18 @@ Extra-source-files:
CHANGELOG
Library
- Exposed-modules: Language.Haskell.Stylish
Hs-source-dirs: lib
Ghc-options: -Wall
+ Exposed-modules:
+ Language.Haskell.Stylish
+ Language.Haskell.Stylish.Step.Imports
+ Language.Haskell.Stylish.Step.LanguagePragmas
+ Language.Haskell.Stylish.Step.SimpleAlign
+ Language.Haskell.Stylish.Step.Tabs
+ Language.Haskell.Stylish.Step.TrailingWhitespace
+ Language.Haskell.Stylish.Step.UnicodeSyntax
+
Other-modules:
Language.Haskell.Stylish.Align
Language.Haskell.Stylish.Block
@@ -36,24 +44,18 @@ Library
Language.Haskell.Stylish.Editor
Language.Haskell.Stylish.Parse
Language.Haskell.Stylish.Step
- Language.Haskell.Stylish.Step.SimpleAlign
- Language.Haskell.Stylish.Step.Imports
- Language.Haskell.Stylish.Step.LanguagePragmas
- Language.Haskell.Stylish.Step.Tabs
- Language.Haskell.Stylish.Step.TrailingWhitespace
- Language.Haskell.Stylish.Step.UnicodeSyntax
Language.Haskell.Stylish.Util
Language.Haskell.Stylish.Verbose
Paths_stylish_haskell
Build-depends:
- aeson >= 0.6 && < 0.12,
+ aeson >= 0.6 && < 1.2,
base >= 4.8 && < 5,
bytestring >= 0.9 && < 0.11,
containers >= 0.3 && < 0.6,
- directory >= 1.1 && < 1.3,
+ directory >= 1.1 && < 1.4,
filepath >= 1.1 && < 1.5,
- haskell-src-exts >= 1.17 && < 1.18,
+ haskell-src-exts >= 1.18 && < 1.20,
mtl >= 2.0 && < 2.3,
syb >= 0.3 && < 0.7,
yaml >= 0.7 && < 0.9
@@ -66,15 +68,15 @@ Executable stylish-haskell
Build-depends:
stylish-haskell,
strict >= 0.3 && < 0.4,
- optparse-applicative >= 0.12 && < 0.13,
+ optparse-applicative >= 0.12 && < 0.14,
-- Copied from regular dependencies...
- aeson >= 0.6 && < 0.12,
+ aeson >= 0.6 && < 1.2,
base >= 4.8 && < 5,
bytestring >= 0.9 && < 0.11,
containers >= 0.3 && < 0.6,
- directory >= 1.1 && < 1.3,
+ directory >= 1.1 && < 1.4,
filepath >= 1.1 && < 1.5,
- haskell-src-exts >= 1.17 && < 1.18,
+ haskell-src-exts >= 1.18 && < 1.20,
mtl >= 2.0 && < 2.3,
syb >= 0.3 && < 0.7,
yaml >= 0.7 && < 0.9
@@ -110,17 +112,17 @@ Test-suite stylish-haskell-tests
Language.Haskell.Stylish.Verbose
Build-depends:
- HUnit >= 1.2 && < 1.4,
+ HUnit >= 1.2 && < 1.6,
test-framework >= 0.4 && < 0.9,
test-framework-hunit >= 0.2 && < 0.4,
-- Copied from regular dependencies...
- aeson >= 0.6 && < 0.12,
+ aeson >= 0.6 && < 1.2,
base >= 4.8 && < 5,
bytestring >= 0.9 && < 0.11,
containers >= 0.3 && < 0.6,
- directory >= 1.1 && < 1.3,
+ directory >= 1.1 && < 1.4,
filepath >= 1.1 && < 1.5,
- haskell-src-exts >= 1.17 && < 1.18,
+ haskell-src-exts >= 1.18 && < 1.20,
mtl >= 2.0 && < 2.3,
syb >= 0.3 && < 0.7,
yaml >= 0.7 && < 0.9
diff --git a/tests/Language/Haskell/Stylish/Parse/Tests.hs b/tests/Language/Haskell/Stylish/Parse/Tests.hs
index 4d3400c..3f2d4a7 100644
--- a/tests/Language/Haskell/Stylish/Parse/Tests.hs
+++ b/tests/Language/Haskell/Stylish/Parse/Tests.hs
@@ -26,6 +26,7 @@ tests = testGroup "Language.Haskell.Stylish.Parse"
, testCase "KindSignatures extension" testKindSignatures
, testCase "StandalonDeriving extension" testStandaloneDeriving
, testCase "UnicodeSyntax extension" testUnicodeSyntax
+ , testCase "XmlSyntax regression" testXmlSyntaxRegression
]
--------------------------------------------------------------------------------
@@ -114,6 +115,11 @@ testUnicodeSyntax = assert $ isRight $ parseModule [] Nothing $ unlines
, "monadic = id"
]
+testXmlSyntaxRegression :: Assertion
+testXmlSyntaxRegression = assert $ isRight $ parseModule [] Nothing $ unlines
+ [ "smaller a b = a <b"
+ ]
+
--------------------------------------------------------------------------------
isRight :: Either a b -> Bool
isRight (Right _) = True
diff --git a/tests/Language/Haskell/Stylish/Step/Imports/Tests.hs b/tests/Language/Haskell/Stylish/Step/Imports/Tests.hs
index 4ed0bd6..c3178ac 100644
--- a/tests/Language/Haskell/Stylish/Step/Imports/Tests.hs
+++ b/tests/Language/Haskell/Stylish/Step/Imports/Tests.hs
@@ -15,14 +15,11 @@ import Language.Haskell.Stylish.Step.Imports
import Language.Haskell.Stylish.Tests.Util
---------------------------------------------------------------------------------
-defaultAlign :: Align
-defaultAlign = Align Global AfterAlias Inline 4 True
-
--------------------------------------------------------------------------------
-fromImportAlign :: ImportAlign -> Align
-fromImportAlign align = defaultAlign { importAlign = align }
+fromImportAlign :: ImportAlign -> Options
+fromImportAlign align = defaultOptions { importAlign = align }
+
--------------------------------------------------------------------------------
tests :: Test
@@ -45,6 +42,11 @@ tests = testGroup "Language.Haskell.Stylish.Step.Imports.Tests"
, testCase "case 16" case16
, testCase "case 17" case17
, testCase "case 18" case18
+ , testCase "case 19" case19
+ , testCase "case 19b" case19b
+ , testCase "case 19d" case19c
+ , testCase "case 19d" case19d
+ , testCase "case 20" case20
]
@@ -184,7 +186,7 @@ case07 = expected @=? testStep (step 80 $ fromImportAlign File) input'
--------------------------------------------------------------------------------
case08 :: Assertion
case08 = expected
- @=? testStep (step 80 $ Align Global WithAlias Inline 4 True) input
+ @=? testStep (step 80 $ Options Global WithAlias Inline Inherit (LPConstant 4) True) input
where
expected = unlines
[ "module Herp where"
@@ -207,7 +209,7 @@ case08 = expected
--------------------------------------------------------------------------------
case09 :: Assertion
case09 = expected
- @=? testStep (step 80 $ Align Global WithAlias Multiline 4 True) input
+ @=? testStep (step 80 $ Options Global WithAlias Multiline Inherit (LPConstant 4) True) input
where
expected = unlines
[ "module Herp where"
@@ -241,7 +243,7 @@ case09 = expected
--------------------------------------------------------------------------------
case10 :: Assertion
case10 = expected
- @=? testStep (step 40 $ Align Group WithAlias Multiline 4 True) input
+ @=? testStep (step 40 $ Options Group WithAlias Multiline Inherit (LPConstant 4) True) input
where
expected = unlines
[ "module Herp where"
@@ -280,7 +282,7 @@ case10 = expected
--------------------------------------------------------------------------------
case11 :: Assertion
case11 = expected
- @=? testStep (step 80 $ Align Group NewLine Inline 4 True) input
+ @=? testStep (step 80 $ Options Group NewLine Inline Inherit (LPConstant 4) True) input
where
expected = unlines
[ "module Herp where"
@@ -308,7 +310,7 @@ case11 = expected
--------------------------------------------------------------------------------
case12 :: Assertion
case12 = expected
- @=? testStep (step 80 $ Align Group NewLine Inline 2 True) input'
+ @=? testStep (step 80 $ Options Group NewLine Inline Inherit (LPConstant 2) True) input'
where
input' = unlines
[ "import Data.List (map)"
@@ -323,7 +325,7 @@ case12 = expected
--------------------------------------------------------------------------------
case13 :: Assertion
case13 = expected
- @=? testStep (step 80 $ Align None WithAlias InlineWithBreak 4 True) input'
+ @=? testStep (step 80 $ Options None WithAlias InlineWithBreak Inherit (LPConstant 4) True) input'
where
input' = unlines
[ "import qualified Data.List as List (concat, foldl, foldr, head, init,"
@@ -341,7 +343,7 @@ case13 = expected
case14 :: Assertion
case14 = expected
@=? testStep
- (step 80 $ Align None WithAlias InlineWithBreak 10 True) expected
+ (step 80 $ Options None WithAlias InlineWithBreak Inherit (LPConstant 10) True) expected
where
expected = unlines
[ "import qualified Data.List as List (concat, map, null, reverse, tail, (++))"
@@ -351,7 +353,7 @@ case14 = expected
--------------------------------------------------------------------------------
case15 :: Assertion
case15 = expected
- @=? testStep (step 80 $ Align None AfterAlias Multiline 4 True) input'
+ @=? testStep (step 80 $ Options None AfterAlias Multiline Inherit (LPConstant 4) True) input'
where
expected = unlines
[ "import Data.Acid (AcidState)"
@@ -377,7 +379,7 @@ case15 = expected
--------------------------------------------------------------------------------
case16 :: Assertion
case16 = expected
- @=? testStep (step 80 $ Align None AfterAlias Multiline 4 False) input'
+ @=? testStep (step 80 $ Options None AfterAlias Multiline Inherit (LPConstant 4) False) input'
where
expected = unlines
[ "import Data.Acid (AcidState)"
@@ -401,7 +403,7 @@ case16 = expected
--------------------------------------------------------------------------------
case17 :: Assertion
case17 = expected
- @=? testStep (step 80 $ Align None AfterAlias Multiline 4 True) input'
+ @=? testStep (step 80 $ Options None AfterAlias Multiline Inherit (LPConstant 4) True) input'
where
expected = unlines
[ "import Control.Applicative (Applicative (pure, (<*>)))"
@@ -419,7 +421,7 @@ case17 = expected
--------------------------------------------------------------------------------
case18 :: Assertion
case18 = expected @=? testStep
- (step 40 $ Align None AfterAlias InlineToMultiline 4 True) input'
+ (step 40 $ Options None AfterAlias InlineToMultiline Inherit (LPConstant 4) True) input'
where
expected = unlines
----------------------------------------
@@ -442,3 +444,90 @@ case18 = expected @=? testStep
, ""
, "import Data.Acid as Acid (closeAcidState, createCheckpoint, openLocalStateFrom)"
]
+
+--------------------------------------------------------------------------------
+case19 :: Assertion
+case19 = expected @=? testStep
+ (step 40 $ Options Global NewLine InlineWithBreak RightAfter (LPConstant 17) True) case19input
+ where
+ expected = unlines
+ ----------------------------------------
+ [ "import Prelude ()"
+ , "import Prelude.Compat hiding"
+ , " (foldMap)"
+ , ""
+ , "import Data.List"
+ , " (foldl', intercalate,"
+ , " intersperse)"
+ ]
+
+case19b :: Assertion
+case19b = expected @=? testStep
+ (step 40 $ Options File NewLine InlineWithBreak RightAfter (LPConstant 17) True) case19input
+ where
+ expected = unlines
+ ----------------------------------------
+ [ "import Prelude ()"
+ , "import Prelude.Compat hiding"
+ , " (foldMap)"
+ , ""
+ , "import Data.List"
+ , " (foldl', intercalate,"
+ , " intersperse)"
+ ]
+
+case19c :: Assertion
+case19c = expected @=? testStep
+ (step 40 $ Options File NewLine InlineWithBreak RightAfter LPModuleName True) case19input
+ where
+ expected = unlines
+ ----------------------------------------
+ [ "import Prelude ()"
+ , "import Prelude.Compat hiding"
+ , " (foldMap)"
+ , ""
+ , "import Data.List"
+ , " (foldl', intercalate,"
+ , " intersperse)"
+ ]
+
+case19d :: Assertion
+case19d = expected @=? testStep
+ (step 40 $ Options Global NewLine InlineWithBreak RightAfter LPModuleName True) case19input
+ where
+ expected = unlines
+ ----------------------------------------
+ [ "import Prelude ()"
+ , "import Prelude.Compat hiding"
+ , " (foldMap)"
+ , ""
+ , "import Data.List"
+ , " (foldl', intercalate,"
+ , " intersperse)"
+ ]
+
+case19input :: String
+case19input = unlines
+ [ "import Prelude.Compat hiding (foldMap)"
+ , "import Prelude ()"
+ , ""
+ , "import Data.List (foldl', intercalate, intersperse)"
+ ]
+
+--------------------------------------------------------------------------------
+case20 :: Assertion
+case20 = expected
+ @=? testStep (step 80 defaultOptions) input'
+ where
+ expected = unlines
+ [ "import {-# SOURCE #-} Data.ByteString as BS"
+ , "import qualified Data.Map as Map"
+ , "import Data.Set (empty)"
+ , "import {-# SOURCE #-} qualified Data.Text as T"
+ ]
+ input' = unlines
+ [ "import {-# SOURCE #-} Data.ByteString as BS"
+ , "import {-# SOURCE #-} qualified Data.Text as T"
+ , "import qualified Data.Map as Map"
+ , "import Data.Set (empty)"
+ ]