Skip to content

Support for records formatting #256

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 36 commits into from
Jan 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
0c9054d
Initial test describing simplest scenario for Data step
EncodePanda Jan 16, 2020
43718c1
[sanity-check] Delete data defs
lukasz-golebiewski Jan 16, 2020
88a5b86
Extract changeDecl
EncodePanda Jan 16, 2020
467a183
First green test :-)
lukasz-golebiewski Jan 16, 2020
fd44a32
Cover case where there are more then one field in data type declaration
EncodePanda Jan 16, 2020
cdc0fbb
Add case03 where a type variable is present
lukasz-golebiewski Jan 16, 2020
1849ed3
Add case04 - multiple declarations
lukasz-golebiewski Jan 16, 2020
e21d226
Make case04 pass
lukasz-golebiewski Jan 16, 2020
df4ccd6
Extend tests with case05
EncodePanda Jan 17, 2020
4577f7a
Add pending case06
EncodePanda Jan 17, 2020
aa1ab20
Fix case 06
lukasz-golebiewski Jan 17, 2020
67436d6
Add case07
EncodePanda Jan 17, 2020
4463267
Add second phantom case
lukasz-golebiewski Jan 17, 2020
60125ce
Add records to config
lukasz-golebiewski Jan 17, 2020
842d3d7
Make indent size configurable for records
lukasz-golebiewski Jan 17, 2020
3b73abc
Fix warnings in Data.hs
lukasz-golebiewski Jan 17, 2020
dfdc6e3
Process derivings during record formatting
lukasz-golebiewski Jan 17, 2020
6b8758f
Do not format when context is present
lukasz-golebiewski Jan 17, 2020
8d2451b
Add case 11 - deriving with DerivingStrategies
EncodePanda Jan 17, 2020
6ee84d1
Bugfix: do not remove empty data declarations
lukasz-golebiewski Jan 17, 2020
caf64da
Update README example with ability to format records
EncodePanda Jan 17, 2020
53d7d53
Add case12 (Point)
lukasz-golebiewski Jan 17, 2020
11785de
Fix case 12
lukasz-golebiewski Jan 17, 2020
6ea58d8
Factor out processName
lukasz-golebiewski Jan 17, 2020
3b9500c
Apply hlint suggestions
lukasz-golebiewski Jan 17, 2020
33bd59a
Extract constructors helper function
EncodePanda Jan 17, 2020
6eb3ae0
Make 'indent' global
lukasz-golebiewski Jan 18, 2020
6e7547c
Remove unused Stylish.records method
lukasz-golebiewski Jan 18, 2020
b33fba1
Fix Config formatting in Config.hs
lukasz-golebiewski Jan 18, 2020
a73a79f
Extract processConstructor function
EncodePanda Jan 20, 2020
7ad3055
Refactor datas function
EncodePanda Jan 20, 2020
0d62b82
Include comments with AST. Two tests are still failing...
EncodePanda Jan 22, 2020
86b6eb8
Fix cases 15 and 16
lukasz-golebiewski Jan 22, 2020
3dc1fb2
Do not format records when comments within
EncodePanda Jan 23, 2020
dcd2d51
Clean-up Data.hs
lukasz-golebiewski Jan 23, 2020
c28c803
Refactor Data.hs
lukasz-golebiewski Jan 23, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,7 @@ import System.Directory (doesFileExist)
import qualified Data.Map as M
import Data.Map ((!), keys, Map)

data Point = Point
{ pointX, pointY :: Double
, pointName :: String
} deriving (Show)
data Point = Point { pointX, pointY :: Double , pointName :: String} deriving (Show)
```

into:
Expand Down
6 changes: 6 additions & 0 deletions data/stylish-haskell.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ steps:
# # true.
# add_language_pragma: true

# Format record definitions
- records: {}

# Align the right hand side of some elements. This is quite conservative
# and only applies to statements where each element occupies a single
# line. All default to true.
Expand Down Expand Up @@ -222,6 +225,9 @@ steps:
# simple_align but is a bit less conservative.
# - squash: {}

# A common indentation setting. Different steps take this into account.
indent: 4

# A common setting is the number of columns (parts of) code will be wrapped
# to. Different steps take this into account.
#
Expand Down
9 changes: 9 additions & 0 deletions lib/Language/Haskell/Stylish/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import qualified System.IO as IO (Newline
import qualified Language.Haskell.Stylish.Config.Cabal as Cabal
import Language.Haskell.Stylish.Config.Internal
import Language.Haskell.Stylish.Step
import qualified Language.Haskell.Stylish.Step.Data as Data
import qualified Language.Haskell.Stylish.Step.Imports as Imports
import qualified Language.Haskell.Stylish.Step.LanguagePragmas as LanguagePragmas
import qualified Language.Haskell.Stylish.Step.SimpleAlign as SimpleAlign
Expand All @@ -52,6 +53,7 @@ type Extensions = [String]
--------------------------------------------------------------------------------
data Config = Config
{ configSteps :: [Step]
, configIndent :: Int
, configColumns :: Maybe Int
, configLanguageExtensions :: [String]
, configNewline :: IO.Newline
Expand Down Expand Up @@ -119,6 +121,7 @@ parseConfig (A.Object o) = do
-- First load the config without the actual steps
config <- Config
<$> pure []
<*> (o A..:? "indent" A..!= 4)
<*> (o A..:! "columns" A..!= Just 80)
<*> (o A..:? "language_extensions" A..!= [])
<*> (o A..:? "newline" >>= parseEnum newlines IO.nativeNewline)
Expand All @@ -141,6 +144,7 @@ parseConfig _ = mzero
catalog :: Map String (Config -> A.Object -> A.Parser Step)
catalog = M.fromList
[ ("imports", parseImports)
, ("records", parseRecords)
, ("language_pragmas", parseLanguagePragmas)
, ("simple_align", parseSimpleAlign)
, ("squash", parseSquash)
Expand Down Expand Up @@ -180,6 +184,11 @@ parseSimpleAlign c o = SimpleAlign.step
where
withDef f k = fromMaybe (f SimpleAlign.defaultConfig) <$> (o A..:? k)

--------------------------------------------------------------------------------
parseRecords :: Config -> A.Object -> A.Parser Step
parseRecords c _ = Data.step
<$> pure (configIndent c)


--------------------------------------------------------------------------------
parseSquash :: Config -> A.Object -> A.Parser Step
Expand Down
66 changes: 66 additions & 0 deletions lib/Language/Haskell/Stylish/Step/Data.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
module Language.Haskell.Stylish.Step.Data where

import Data.List (find, intercalate)
import Data.Maybe (maybeToList)
import qualified Language.Haskell.Exts as H
import Language.Haskell.Exts.Comments
import Language.Haskell.Stylish.Block
import Language.Haskell.Stylish.Editor
import Language.Haskell.Stylish.Step
import Language.Haskell.Stylish.Util
import Prelude hiding (init)

datas :: H.Module l -> [H.Decl l]
datas (H.Module _ _ _ _ decls) = decls
datas _ = []

type ChangeLine = Change String

step :: Int -> Step
step indentSize = makeStep "Data" (step' indentSize)

step' :: Int -> Lines -> Module -> Lines
step' indentSize ls (module', allComments) = applyChanges changes ls
where
datas' = datas $ fmap linesFromSrcSpan module'
changes = datas' >>= maybeToList . changeDecl allComments indentSize

findComment :: LineBlock -> [Comment] -> Maybe Comment
findComment lb = find commentOnLine
where
commentOnLine (Comment _ (H.SrcSpan _ start _ end _) _) =
blockStart lb == start && blockEnd lb == end

commentsWithin :: LineBlock -> [Comment] -> [Comment]
commentsWithin lb = filter within
where
within (Comment _ (H.SrcSpan _ start _ end _) _) =
start >= blockStart lb && end <= blockEnd lb

changeDecl :: [Comment] -> Int -> H.Decl LineBlock -> Maybe ChangeLine
changeDecl _ _ (H.DataDecl _ (H.DataType _) Nothing _ [] _) = Nothing
changeDecl allComments indentSize (H.DataDecl block (H.DataType _) Nothing dhead decls derivings)
| null $ commentsWithin block allComments = Just $ change block (const $ concat newLines)
| otherwise = Nothing
where
newLines = fmap constructors zipped ++ [fmap (indented . H.prettyPrint) derivings]
zipped = zip decls ([1..] ::[Int])
constructors (decl, 1) = processConstructor allComments typeConstructor indentSize decl
constructors (decl, _) = processConstructor allComments (indented "| ") indentSize decl
typeConstructor = "data " <> H.prettyPrint dhead <> " = "
indented = indent indentSize
changeDecl _ _ _ = Nothing

processConstructor :: [Comment] -> String -> Int -> H.QualConDecl LineBlock -> [String]
processConstructor allComments init indentSize (H.QualConDecl _ _ _ (H.RecDecl _ dname fields)) = do
init <> H.prettyPrint dname : n1 : ns ++ [indented "}"]
where
n1 = processName "{ " ( extractField $ head fields)
ns = fmap (processName ", " . extractField) (tail fields)
processName prefix (fnames, _type, Nothing) =
indented prefix <> intercalate ", " (fmap H.prettyPrint fnames) <> " :: " <> H.prettyPrint _type
processName prefix (fnames, _type, (Just (Comment _ _ c))) =
indented prefix <> intercalate ", " (fmap H.prettyPrint fnames) <> " :: " <> H.prettyPrint _type <> " --" <> c
extractField (H.FieldDecl lb names _type) = (names, _type, findComment lb allComments)
indented = indent indentSize
processConstructor _ init _ decl = [init <> trimLeft (H.prettyPrint decl)]
3 changes: 3 additions & 0 deletions stylish-haskell.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Library

Exposed-modules:
Language.Haskell.Stylish
Language.Haskell.Stylish.Step.Data
Language.Haskell.Stylish.Step.Imports
Language.Haskell.Stylish.Step.LanguagePragmas
Language.Haskell.Stylish.Step.SimpleAlign
Expand Down Expand Up @@ -107,6 +108,8 @@ Test-suite stylish-haskell-tests
Language.Haskell.Stylish.Step
Language.Haskell.Stylish.Step.Imports
Language.Haskell.Stylish.Step.Imports.Tests
Language.Haskell.Stylish.Step.Data
Language.Haskell.Stylish.Step.Data.Tests
Language.Haskell.Stylish.Step.LanguagePragmas
Language.Haskell.Stylish.Step.LanguagePragmas.Tests
Language.Haskell.Stylish.Step.SimpleAlign
Expand Down
2 changes: 2 additions & 0 deletions tests/Language/Haskell/Stylish/Config/Tests.hs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ dotStylish = unlines $
, " align: false"
, " remove_redundant: true"
, " - trailing_whitespace: {}"
, " - records: {}"
, "indent: 2"
, "columns: 110"
, "language_extensions:"
, " - TemplateHaskell"
Expand Down
Loading