{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RankNTypes #-} module Main where import qualified Control.Exception as E import Control.Monad import Data.Monoid ((<>)) import Data.Version (showVersion) import qualified Data.Yaml as Yaml import HIE.Bios.Types import Haskell.Ide.Engine.Cradle (findLocalCradle, cradleDisplay) import Haskell.Ide.Engine.MonadFunctions import Haskell.Ide.Engine.MonadTypes import Haskell.Ide.Engine.Options import Haskell.Ide.Engine.Scheduler import Haskell.Ide.Engine.Server import Haskell.Ide.Engine.Version import qualified Language.Haskell.LSP.Core as Core import Options.Applicative.Simple import qualified Paths_haskell_ide_engine as Meta import System.Directory import System.Environment import System.FilePath (()) import System.Info import System.IO import qualified System.Log.Logger as L -- --------------------------------------------------------------------- -- plugins import Haskell.Ide.Engine.Plugin.ApplyRefact import Haskell.Ide.Engine.Plugin.Brittany import Haskell.Ide.Engine.Plugin.Example2 import Haskell.Ide.Engine.Plugin.Floskell import Haskell.Ide.Engine.Plugin.Generic import Haskell.Ide.Engine.Plugin.GhcMod -- import Haskell.Ide.Engine.Plugin.HaRe import Haskell.Ide.Engine.Plugin.Haddock import Haskell.Ide.Engine.Plugin.HfaAlign import Haskell.Ide.Engine.Plugin.HsImport import Haskell.Ide.Engine.Plugin.Liquid import Haskell.Ide.Engine.Plugin.Package import Haskell.Ide.Engine.Plugin.Pragmas -- --------------------------------------------------------------------- -- | This will be read from a configuration, eventually plugins :: Bool -> IdePlugins plugins includeExamples = pluginDescToIdePlugins allPlugins where allPlugins = if includeExamples then basePlugins ++ examplePlugins else basePlugins basePlugins = [ applyRefactDescriptor "applyrefact" , brittanyDescriptor "brittany" , haddockDescriptor "haddock" -- , hareDescriptor "hare" , hsimportDescriptor "hsimport" , liquidDescriptor "liquid" , packageDescriptor "package" , pragmasDescriptor "pragmas" , floskellDescriptor "floskell" , genericDescriptor "generic" , ghcmodDescriptor "ghcmod" ] examplePlugins = [example2Descriptor "eg2" ,hfaAlignDescriptor "hfaa" ] -- --------------------------------------------------------------------- main :: IO () main = do let numericVersion :: Parser (a -> a) numericVersion = infoOption (showVersion Meta.version) (long "numeric-version" <> help "Show only version number") compiler :: Parser (a -> a) compiler = infoOption hieGhcDisplayVersion (long "compiler" <> help "Show only compiler and version supported") -- Parse the options and run (global, ()) <- simpleOptions hieVersion "haskell-ide-engine - Provide a common engine to power any Haskell IDE" "" (numericVersion <*> compiler <*> globalOptsParser) empty run global -- --------------------------------------------------------------------- run :: GlobalOpts -> IO () run opts = do hSetBuffering stderr LineBuffering let mLogFileName = optLogFile opts logLevel = if optDebugOn opts then L.DEBUG else L.INFO Core.setupLogger mLogFileName ["hie", "hie-bios"] logLevel origDir <- getCurrentDirectory maybe (pure ()) setCurrentDirectory $ projectRoot opts progName <- getProgName args <- getArgs if optLsp opts then do -- Start up in LSP mode logm $ "Run entered for HIE(" ++ progName ++ ") " ++ hieVersion logm $ "Operating as a LSP server on stdio" logm $ "Current directory:" ++ origDir logm $ "Operating system:" ++ os logm $ "args:" ++ show args let initOpts = defaultCradleOpts { cradleOptsVerbosity = verbosity } verbosity = if optBiosVerbose opts then Verbose else Silent when (optBiosVerbose opts) $ logm "Enabling verbose mode for hie-bios. This option currently doesn't do anything." when (optExamplePlugin opts) $ logm "Enabling Example2 plugin, will insert constant diagnostics etc." let plugins' = plugins (optExamplePlugin opts) -- launch the dispatcher. scheduler <- newScheduler plugins' initOpts server scheduler origDir plugins' (optCaptureFile opts) else do -- Provide debug info cliOut $ "Running HIE(" ++ progName ++ ")" cliOut $ " " ++ hieVersion cliOut $ "To run as a LSP server on stdio, provide the '--lsp' argument" cliOut $ "Current directory:" ++ origDir -- args <- getArgs cliOut $ "\nargs:" ++ show args cliOut $ "\nLooking for project config cradle...\n" ecradle <- getCradleInfo origDir case ecradle of Left e -> cliOut $ "Could not get cradle:" ++ show e Right cradle -> cliOut $ "Cradle:" ++ cradleDisplay cradle -- --------------------------------------------------------------------- getCradleInfo :: FilePath -> IO (Either Yaml.ParseException Cradle) getCradleInfo currentDir = do let dummyCradleFile = currentDir "File.hs" cradleRes <- E.try (findLocalCradle dummyCradleFile) return cradleRes -- --------------------------------------------------------------------- cliOut :: String -> IO () cliOut = putStrLn -- ---------------------------------------------------------------------