Skip to content
This repository was archived by the owner on Oct 7, 2020. It is now read-only.

[WIP] stylish-haskell plugin #1618

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
39afabc
First draft of the Stylish (Haskell) plugin
lukasz-golebiewski Jan 25, 2020
577519f
Add stylish formatter provider to HSImportSpec (failing)
EncodePanda Jan 25, 2020
50f0a65
Extract formatLspConfig in FormatSpec
EncodePanda Jan 26, 2020
4566617
Add first working draft of the stylish plugin
lukasz-golebiewski Jan 30, 2020
e631aa9
Update stack.yaml
lukasz-golebiewski Jan 31, 2020
a64db52
Update stack.yaml
lukasz-golebiewski Jan 31, 2020
3bb0de8
Add stylish-haskell version to *.cabal
lukasz-golebiewski Feb 2, 2020
9754065
Add stylish-haskell to stack*.yaml
lukasz-golebiewski Feb 2, 2020
87ca5fd
Force HsYaml versions
lukasz-golebiewski Feb 2, 2020
ea10da5
Add HsYaml to .cabal
lukasz-golebiewski Feb 2, 2020
1ef9650
Update cabal index snapshot
Avi-D-coder Feb 2, 2020
c0e5559
Merge branch 'master' into stylish-support
Avi-D-coder Feb 2, 2020
d143052
Add stylish with deps to stack yaml 8.8.2
lukasz-golebiewski Feb 4, 2020
9e59e29
Add cabal-3.0.0.0
lukasz-golebiewski Feb 4, 2020
d8f274c
Merge branch 'master' of github.com:haskell/haskell-ide-engine into s…
lukasz-golebiewski Feb 4, 2020
26f9e87
Revert "Add cabal-3.0.0.0"
lukasz-golebiewski Feb 4, 2020
6f91f83
Add dependency on vector to stack-8.4.4
lukasz-golebiewski Feb 5, 2020
a1a6f75
Add dependency on Cabal-3.0.0.0
lukasz-golebiewski Feb 5, 2020
15e816d
Set cabal to 2.4.1.0
lukasz-golebiewski Feb 5, 2020
5988529
Downgrade cabal to 2.2.0.1
lukasz-golebiewski Feb 8, 2020
df7cce7
Merge branch 'master' of github.com:haskell/haskell-ide-engine into s…
lukasz-golebiewski Feb 8, 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
2 changes: 2 additions & 0 deletions app/MainHie.hs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import Haskell.Ide.Engine.Plugin.Liquid
import Haskell.Ide.Engine.Plugin.Ormolu
import Haskell.Ide.Engine.Plugin.Package
import Haskell.Ide.Engine.Plugin.Pragmas
import Haskell.Ide.Engine.Plugin.Stylish (stylishDescriptor)

-- ---------------------------------------------------------------------

Expand All @@ -74,6 +75,7 @@ plugins includeExamples = pluginDescToIdePlugins allPlugins
, genericDescriptor "generic"
, ghcmodDescriptor "ghcmod"
, ormoluDescriptor "ormolu"
, stylishDescriptor "stylish"
]
examplePlugins =
[example2Descriptor "eg2"
Expand Down
2 changes: 2 additions & 0 deletions haskell-ide-engine.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ library
Haskell.Ide.Engine.Plugin.Package
Haskell.Ide.Engine.Plugin.Package.Compat
Haskell.Ide.Engine.Plugin.Pragmas
Haskell.Ide.Engine.Plugin.Stylish
Haskell.Ide.Engine.Plugin.Generic
Haskell.Ide.Engine.Plugin.GhcMod
Haskell.Ide.Engine.Scheduler
Expand Down Expand Up @@ -90,6 +91,7 @@ library
, safe
, sorted-list >= 0.2.1.0
, stm
, stylish-haskell
, syb
, tagsoup
, text
Expand Down
43 changes: 43 additions & 0 deletions src/Haskell/Ide/Engine/Plugin/Stylish.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{-# LANGUAGE OverloadedStrings #-}
module Haskell.Ide.Engine.Plugin.Stylish where

import Control.Monad.IO.Class (liftIO)
import Data.Aeson (Value (Null))
import Data.List (intercalate)
import qualified Data.Text as T
import Haskell.Ide.Engine.MonadTypes
import Haskell.Ide.Engine.PluginUtils (fullRange, pluginGetFile)
import Language.Haskell.Stylish (ConfigPath (..), format)


stylishDescriptor :: PluginId -> PluginDescriptor
stylishDescriptor plId = PluginDescriptor
{ pluginId = plId
, pluginName = "Stylish"
, pluginDesc = "Stylish is a tool to format source code."
, pluginCommands = []
, pluginCodeActionProvider = Nothing
, pluginDiagnosticProvider = Nothing
, pluginHoverProvider = Nothing
, pluginSymbolProvider = Nothing
, pluginFormattingProvider = Just provider
}

provider :: FormattingProvider
provider contents uri typ _ =
case typ of
FormatRange _ ->
return $ IdeResultFail (IdeError PluginError (T.pack "Selection formatting for Stylish is not currently supported.") Null)
FormatText -> pluginGetFile "stylish:" uri $ \file -> do
res <- liftIO $ runStylish Nothing file contents
case res of
Left err -> return $ IdeResultFail
(IdeError PluginError
(T.pack $ "stylish: " ++ err)
Null
)
Right new -> return $ IdeResultOk [TextEdit (fullRange contents) (T.pack $ ((intercalate "\n" new) <> "\n"))]


runStylish :: Maybe ConfigPath -> FilePath -> T.Text -> IO (Either String [String])
runStylish config file contents = format config (Just file) (T.unpack contents)
3 changes: 3 additions & 0 deletions stack.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,12 @@ extra-deps:
- hie-bios-0.3.2
- hlint-2.2.8
- hsimport-0.11.0
- HsYAML-0.2.1.0@sha256:e4677daeba57f7a1e9a709a1f3022fe937336c91513e893166bd1f023f530d68,5311
- HsYAML-aeson-0.2.0.0@sha256:04796abfc01cffded83f37a10e6edba4f0c0a15d45bef44fc5bb4313d9c87757,1791
- lsp-test-0.10.0.0
- monad-dijkstra-0.1.1.2@rev:1
- parser-combinators-1.2.1
- stylish-haskell-0.10.0.0
- ormolu-0.0.3.1
- syz-0.2.0.0
- temporary-1.2.1.1
Expand Down
11 changes: 5 additions & 6 deletions test/functional/FormatSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@ spec = do
documentContents doc >>= liftIO . (`shouldBe` formattedRangeTabSize5)

describe "formatting provider" $ do
let formatLspConfig provider =
object [ "languageServerHaskell" .= object ["formattingProvider" .= (provider :: Value)] ]
formatConfig provider = defaultConfig { lspConfig = Just (formatLspConfig provider) }
let formatConfig provider = defaultConfig { lspConfig = Just (formatLspConfig provider) }

it "respects none" $ runSessionWithConfig (formatConfig "none") hieCommand fullCaps "test/testdata" $ do
doc <- openDoc "Format.hs" "haskell"
Expand Down Expand Up @@ -93,9 +91,7 @@ spec = do
"foo x y = do\n print x\n return 42\n"]

describe "ormolu" $ do
let formatLspConfig provider =
object [ "languageServerHaskell" .= object ["formattingProvider" .= (provider :: Value)] ]


it "formats correctly" $ runSession hieCommand fullCaps "test/testdata" $ do
sendNotification WorkspaceDidChangeConfiguration (DidChangeConfigurationParams (formatLspConfig "ormolu"))
doc <- openDoc "Format.hs" "haskell"
Expand All @@ -107,6 +103,9 @@ spec = do
GHC86 -> formatted
_ -> liftIO $ docContent `shouldBe` unchangedOrmolu

formatLspConfig :: Value -> Value
formatLspConfig provider =
object [ "languageServerHaskell" .= object ["formattingProvider" .= provider] ]

formattedDocTabSize2 :: T.Text
formattedDocTabSize2 =
Expand Down
38 changes: 30 additions & 8 deletions test/unit/HsImportSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
module HsImportSpec where

import Control.Monad.IO.Class
import qualified Data.Text as T
import qualified Data.HashMap.Strict as Map
import qualified Data.HashMap.Strict as Map
import qualified Data.Text as T
import qualified Haskell.Ide.Engine.Config as Config
import Haskell.Ide.Engine.MonadTypes
import Haskell.Ide.Engine.PluginUtils
import Haskell.Ide.Engine.Plugin.HsImport
import qualified Haskell.Ide.Engine.Config as Config
import qualified Haskell.Ide.Engine.Plugin.Brittany as Brittany
import qualified Haskell.Ide.Engine.Plugin.Ormolu as Ormolu
import qualified Haskell.Ide.Engine.Plugin.Floskell as Floskell
import Haskell.Ide.Engine.Plugin.HsImport
import qualified Haskell.Ide.Engine.Plugin.Ormolu as Ormolu
import qualified Haskell.Ide.Engine.Plugin.Stylish as Stylish
import Haskell.Ide.Engine.PluginUtils
import System.Directory
import System.FilePath
import Test.Hspec
Expand All @@ -31,6 +32,7 @@ testPlugins = pluginDescToIdePlugins
[ Brittany.brittanyDescriptor "brittany"
, Floskell.floskellDescriptor "floskell"
, Ormolu.ormoluDescriptor "ormolu"
, Stylish.stylishDescriptor "stylish"
]

codeActionImportList :: FilePath
Expand Down Expand Up @@ -126,7 +128,27 @@ hsImportSpec = do
]
_ -> it "is NOP formatter" $
pendingWith "Ormolu only supported by GHC >= 8.6. Need to restore this."

describe "formats with stylish" $ hsImportSpecRunner "stylish"
[ -- Expected output for simple format.
[ TextEdit (Range (toPos (2, 1)) (toPos (2, 1))) "import Control.Monad\n"
]
, [ TextEdit (Range (toPos (2, 1)) (toPos (2, 1))) "import Control.Monad (when)\n"
]
, [ TextEdit (Range (toPos (2, 1)) (toPos (2, 1))) "import Data.Maybe (Maybe)\n"
]
, [ TextEdit (Range (toPos (2, 1)) (toPos (2, 1))) "import Data.Maybe (Maybe (..))\n"
]
, [ TextEdit (Range (toPos (2, 1)) (toPos (2, 1))) "import Data.Maybe (Maybe (Nothing))\n"
]
, [ TextEdit (Range (toPos (2, 1)) (toPos (2, 1))) "import Data.Function (($))\n"
]
, [ TextEdit (Range (toPos (2, 1)) (toPos (2, 32))) "import System.IO (IO, hPutStrLn)"
]
, [ TextEdit (Range (toPos (3, 1)) (toPos (3, 99))) $
"import Data.List (cons, find, head, init, last, length, null, reverse,\n" <>
" tail, uncons, union, (\\\\))"
]
]
-- ---------------------------------------------------------------------
-- Parameterized HsImport Spec.
-- ---------------------------------------------------------------------
Expand Down Expand Up @@ -196,4 +218,4 @@ expectHsImportResult formatterName fp uri expectedChanges act = do
IdeResultOk (WorkspaceEdit (Just changes) _) <- runSingle' (setFormatter formatterName) testPlugins fp act
case Map.lookup uri changes of
Just (List val) -> val `shouldBe` expectedChanges
Nothing -> fail "No Change found"
Nothing -> fail "No Change found"