hls-fourmolu-plugin 2.0.0.1 → 2.1.0.0
raw patch · 4 files changed
+101/−71 lines, 4 filesdep +mtldep +transformersdep ~fourmoludep ~ghcidedep ~hls-plugin-apiPVP ok
version bump matches the API change (PVP)
Dependencies added: mtl, transformers
Dependency ranges changed: fourmolu, ghcide, hls-plugin-api, hls-test-utils
API changes (from Hackage documentation)
- Ide.Plugin.Fourmolu.Shim: addFixityOverrides :: FixityMap -> Config region -> Config region
+ Ide.Plugin.Fourmolu.Shim: addFixityOverrides :: FixityOverrides -> Config region -> Config region
Files
- hls-fourmolu-plugin.cabal +7/−5
- src/Ide/Plugin/Fourmolu.hs +77/−56
- src/Ide/Plugin/Fourmolu/Shim.hs +14/−7
- test/Main.hs +3/−3
hls-fourmolu-plugin.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: hls-fourmolu-plugin-version: 2.0.0.1+version: 2.1.0.0 synopsis: Integration with the Fourmolu code formatter description: Please see the README on GitHub at <https://github.com/haskell/haskell-language-server#readme>@@ -32,15 +32,17 @@ build-depends: , base >=4.12 && <5 , filepath- , fourmolu ^>=0.3 || ^>=0.4 || ^>= 0.6 || ^>= 0.7 || ^>= 0.8 || ^>= 0.9 || ^>= 0.10 || ^>= 0.11 || ^>= 0.12+ , fourmolu ^>=0.3 || ^>=0.4 || ^>= 0.6 || ^>= 0.7 || ^>= 0.8 || ^>= 0.9 || ^>= 0.10 || ^>= 0.11 || ^>= 0.12 || ^>= 0.13 , ghc , ghc-boot-th- , ghcide == 2.0.0.1- , hls-plugin-api == 2.0.0.1+ , ghcide == 2.1.0.0+ , hls-plugin-api == 2.1.0.0 , lens , lsp+ , mtl , process-extras >= 0.7.1 , text+ , transformers -- fourmolu 0.9.0 fails to build on Windows CI for reasons unknown if impl(ghc >= 9.2) && os(windows) && impl(ghc < 9.4)@@ -63,5 +65,5 @@ , filepath , hls-fourmolu-plugin , hls-plugin-api- , hls-test-utils == 2.0.0.1+ , hls-test-utils == 2.1.0.0 , lsp-test
src/Ide/Plugin/Fourmolu.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE DisambiguateRecordFields #-} {-# LANGUAGE LambdaCase #-}@@ -5,7 +6,7 @@ {-# LANGUAGE OverloadedLabels #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeApplications #-}-{-# LANGUAGE CPP #-}+{-# LANGUAGE TypeOperators #-} module Ide.Plugin.Fourmolu ( descriptor,@@ -13,12 +14,18 @@ LogEvent, ) where -import Control.Exception (IOException, try)+import Control.Exception (IOException, handle, try) import Control.Lens ((^.))-import Control.Monad-import Control.Monad.IO.Class-import Data.Bifunctor (bimap, first)-import Data.Maybe+import Control.Monad (guard)+import Control.Monad.Error.Class (MonadError (throwError))+import Control.Monad.Trans.Except (ExceptT (..), mapExceptT,+ runExceptT)++import Control.Monad.IO.Class (MonadIO (liftIO))+import Control.Monad.Trans.Class (MonadTrans (lift))+import Data.Bifunctor (bimap)+import Data.List (intercalate)+import Data.Maybe (catMaybes) import Data.Text (Text) import qualified Data.Text as T import Development.IDE hiding (pluginHandlers)@@ -26,13 +33,15 @@ hang, vcat) import qualified Development.IDE.GHC.Compat.Util as S import GHC.LanguageExtensions.Type (Extension (Cpp))+import Ide.Plugin.Error import Ide.Plugin.Fourmolu.Shim import Ide.Plugin.Properties import Ide.PluginUtils (makeDiffTextEdit) import Ide.Types+import Language.LSP.Protocol.Lens (HasTabSize (tabSize))+import Language.LSP.Protocol.Message+import Language.LSP.Protocol.Types import Language.LSP.Server hiding (defaultConfig)-import Language.LSP.Types hiding (line)-import Language.LSP.Types.Lens (HasTabSize (tabSize)) import Ormolu import System.Exit import System.FilePath@@ -56,52 +65,20 @@ False provider :: Recorder (WithPriority LogEvent) -> PluginId -> FormattingHandler IdeState-provider recorder plId ideState typ contents fp fo = withIndefiniteProgress title Cancellable $ do+provider recorder plId ideState typ contents fp fo = ExceptT $ withIndefiniteProgress title Cancellable $ runExceptT $ do fileOpts <- maybe [] (convertDynFlags . hsc_dflags . hscEnv) <$> liftIO (runAction "Fourmolu" ideState $ use GhcSession fp) useCLI <- liftIO $ runAction "Fourmolu" ideState $ usePropertyAction #external plId properties if useCLI- then liftIO- . fmap (join . first (mkError . show))- . try @IOException- $ do- CLIVersionInfo{noCabal} <- do -- check Fourmolu version so that we know which flags to use- (exitCode, out, _err) <- readCreateProcessWithExitCode ( proc "fourmolu" ["-v"] ) ""- let version = do- guard $ exitCode == ExitSuccess- "fourmolu" : v : _ <- pure $ T.words out- traverse (readMaybe @Int . T.unpack) $ T.splitOn "." v- case version of- Just v -> pure CLIVersionInfo- { noCabal = v >= [0, 7]- }- Nothing -> do- logWith recorder Warning $ NoVersion out- pure CLIVersionInfo- { noCabal = True- }- (exitCode, out, err) <- -- run Fourmolu- readCreateProcessWithExitCode- ( proc "fourmolu" $- map ("-o" <>) fileOpts- <> mwhen noCabal ["--no-cabal"]- <> catMaybes- [ ("--start-line=" <>) . show <$> regionStartLine region- , ("--end-line=" <>) . show <$> regionEndLine region- ]- ){cwd = Just $ takeDirectory fp'}- contents- case exitCode of- ExitSuccess -> do- logWith recorder Debug $ StdErr err- pure . Right $ makeDiffTextEdit contents out- ExitFailure n -> do- logWith recorder Info $ StdErr err- pure . Left . responseError $ "Fourmolu failed with exit code " <> T.pack (show n)+ then mapExceptT liftIO $ ExceptT+ $ handle @IOException+ (pure . Left . PluginInternalError . T.pack . show)+ $ runExceptT $ cliHandler fileOpts else do- let format fourmoluConfig =- bimap (mkError . show) (makeDiffTextEdit contents)+ logWith recorder Debug $ LogCompiledInVersion VERSION_fourmolu+ let format fourmoluConfig = ExceptT $+ bimap (PluginInternalError . T.pack . show) (InL . makeDiffTextEdit contents) #if MIN_VERSION_fourmolu(0,11,0) <$> try @OrmoluException (ormolu config fp' contents) #else@@ -121,37 +98,76 @@ defaultPrinterOpts } in liftIO (loadConfigFile fp') >>= \case- ConfigLoaded file opts -> liftIO $ do+ ConfigLoaded file opts -> do logWith recorder Info $ ConfigPath file- format opts- ConfigNotFound searchDirs -> liftIO $ do+ mapExceptT liftIO $ format opts+ ConfigNotFound searchDirs -> do logWith recorder Info $ NoConfigPath searchDirs- format emptyConfig+ mapExceptT liftIO $ format emptyConfig ConfigParseError f err -> do- sendNotification SWindowShowMessage $+ lift $ sendNotification SMethod_WindowShowMessage $ ShowMessageParams- { _xtype = MtError+ { _type_ = MessageType_Error , _message = errorMessage }- return . Left $ responseError errorMessage+ throwError $ PluginInternalError errorMessage where errorMessage = "Failed to load " <> T.pack f <> ": " <> T.pack (showParseError err) where fp' = fromNormalizedFilePath fp title = "Formatting " <> T.pack (takeFileName fp')- mkError = responseError . ("Fourmolu: " <>) . T.pack lspPrinterOpts = mempty{poIndentation = Just $ fromIntegral $ fo ^. tabSize} region = case typ of FormatText -> RegionIndices Nothing Nothing FormatRange (Range (Position sl _) (Position el _)) -> RegionIndices (Just $ fromIntegral $ sl + 1) (Just $ fromIntegral $ el + 1)+ cliHandler :: [String] -> ExceptT PluginError IO ([TextEdit] |? Null)+ cliHandler fileOpts = do+ CLIVersionInfo{noCabal} <- do -- check Fourmolu version so that we know which flags to use+ (exitCode, out, _err) <- liftIO $ readCreateProcessWithExitCode ( proc "fourmolu" ["-v"] ) ""+ let version = do+ guard $ exitCode == ExitSuccess+ "fourmolu" : v : _ <- pure $ T.words out+ traverse (readMaybe @Int . T.unpack) $ T.splitOn "." v+ case version of+ Just v -> do+ logWith recorder Debug $ LogExternalVersion v+ pure CLIVersionInfo+ { noCabal = v >= [0, 7]+ }+ Nothing -> do+ logWith recorder Debug $ LogExternalVersion []+ logWith recorder Warning $ NoVersion out+ pure CLIVersionInfo+ { noCabal = True+ }+ (exitCode, out, err) <- -- run Fourmolu+ liftIO $ readCreateProcessWithExitCode+ ( proc "fourmolu" $+ map ("-o" <>) fileOpts+ <> mwhen noCabal ["--no-cabal"]+ <> catMaybes+ [ ("--start-line=" <>) . show <$> regionStartLine region+ , ("--end-line=" <>) . show <$> regionEndLine region+ ]+ ){cwd = Just $ takeDirectory fp'}+ contents+ case exitCode of+ ExitSuccess -> do+ logWith recorder Debug $ StdErr err+ pure $ InL $ makeDiffTextEdit contents out+ ExitFailure n -> do+ logWith recorder Info $ StdErr err+ throwError $ PluginInternalError $ "Fourmolu failed with exit code " <> T.pack (show n) data LogEvent = NoVersion Text | ConfigPath FilePath | NoConfigPath [FilePath] | StdErr Text+ | LogCompiledInVersion String+ | LogExternalVersion [Int] deriving (Show) instance Pretty LogEvent where@@ -161,6 +177,11 @@ NoConfigPath ps -> "No " <> pretty configFileName <> " found in any of:" <> line <> indent 2 (vsep (map (pretty . show) ps)) StdErr t -> "Fourmolu stderr:" <> line <> indent 2 (pretty t)+ LogCompiledInVersion v -> "Using compiled in fourmolu-" <> pretty v+ LogExternalVersion v ->+ "Using external fourmolu"+ <> if null v then "" else "-"+ <> pretty (intercalate "." $ map show v) convertDynFlags :: DynFlags -> [String] convertDynFlags df =
src/Ide/Plugin/Fourmolu/Shim.hs view
@@ -21,13 +21,15 @@ {-- Backport FourmoluConfig --} -#if !MIN_VERSION_fourmolu(0,7,0)+#if MIN_VERSION_fourmolu(0,7,0)+-- these functions are now defined+#else type FourmoluConfig = PrinterOptsPartial cfgFilePrinterOpts :: FourmoluConfig -> PrinterOptsPartial cfgFilePrinterOpts = id -cfgFileFixities :: FourmoluConfig -> FixityMap+cfgFileFixities :: FourmoluConfig -> FixityOverrides cfgFileFixities _ = mempty #endif @@ -45,15 +47,20 @@ emptyConfig = mempty #endif -{-- Backport FixityMap --}+{-- Backport FixityOverrides --} -#if MIN_VERSION_fourmolu(0,7,0)-addFixityOverrides :: FixityMap -> Config region -> Config region+#if MIN_VERSION_fourmolu(0,13,0)+addFixityOverrides :: FixityOverrides -> Config region -> Config region addFixityOverrides fixities cfg = cfg{cfgFixityOverrides = fixities}+#elif MIN_VERSION_fourmolu(0,7,0)+type FixityOverrides = FixityMap++addFixityOverrides :: FixityOverrides -> Config region -> Config region+addFixityOverrides fixities cfg = cfg{cfgFixityOverrides = fixities} #else-type FixityMap = ()+type FixityOverrides = () -addFixityOverrides :: FixityMap -> Config region -> Config region+addFixityOverrides :: FixityOverrides -> Config region -> Config region addFixityOverrides _ = id #endif
test/Main.hs view
@@ -6,9 +6,9 @@ import Data.Aeson import Data.Functor import Ide.Plugin.Config-import qualified Ide.Plugin.Fourmolu as Fourmolu+import qualified Ide.Plugin.Fourmolu as Fourmolu+import Language.LSP.Protocol.Types import Language.LSP.Test-import Language.LSP.Types import System.FilePath import Test.Hls @@ -26,7 +26,7 @@ (if cli then "cli" else "lib") [ goldenWithFourmolu cli "formats correctly" "Fourmolu" "formatted" $ \doc -> do formatDoc doc (FormattingOptions 4 True Nothing Nothing Nothing)- , goldenWithFourmolu cli "formats imports correctly" "Fourmolu" "formatted" $ \doc -> do+ , goldenWithFourmolu cli "formats imports correctly" "Fourmolu2" "formatted" $ \doc -> do formatDoc doc (FormattingOptions 4 True Nothing Nothing Nothing) ]