packages feed

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 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)         ]