From 6c7715b7fb68943926176bca5c0cbe36cae36bed Mon Sep 17 00:00:00 2001 From: Luke Lau Date: Sat, 21 Dec 2019 23:11:28 +0000 Subject: [PATCH 1/5] Remove JSON transport (2015-2019) Also demote Hoogle to Support since it no longer needs to provide commands. --- app/MainHie.hs | 11 +- haskell-ide-engine.cabal | 3 +- src/Haskell/Ide/Engine/LSP/Completions.hs | 4 +- src/Haskell/Ide/Engine/Options.hs | 8 -- src/Haskell/Ide/Engine/Plugin/Haddock.hs | 2 +- src/Haskell/Ide/Engine/Plugin/HsImport.hs | 2 +- src/Haskell/Ide/Engine/Plugin/Package.hs | 2 +- .../Ide/Engine/{Plugin => Support}/Hoogle.hs | 64 ++------- src/Haskell/Ide/Engine/Transport/JsonStdio.hs | 127 ------------------ src/Haskell/Ide/Engine/Transport/LspStdio.hs | 2 +- test/unit/HooglePluginSpec.hs | 8 +- 11 files changed, 26 insertions(+), 207 deletions(-) rename src/Haskell/Ide/Engine/{Plugin => Support}/Hoogle.hs (83%) delete mode 100644 src/Haskell/Ide/Engine/Transport/JsonStdio.hs diff --git a/app/MainHie.hs b/app/MainHie.hs index 27e2770f3..eda552266 100644 --- a/app/MainHie.hs +++ b/app/MainHie.hs @@ -10,7 +10,6 @@ import Haskell.Ide.Engine.MonadTypes import Haskell.Ide.Engine.Options import Haskell.Ide.Engine.Scheduler import Haskell.Ide.Engine.Transport.LspStdio -import Haskell.Ide.Engine.Transport.JsonStdio import qualified Language.Haskell.LSP.Core as Core import Options.Applicative.Simple import qualified Paths_haskell_ide_engine as Meta @@ -31,7 +30,6 @@ import Haskell.Ide.Engine.Plugin.Bios -- import Haskell.Ide.Engine.Plugin.HaRe import Haskell.Ide.Engine.Plugin.Haddock import Haskell.Ide.Engine.Plugin.HfaAlign -import Haskell.Ide.Engine.Plugin.Hoogle import Haskell.Ide.Engine.Plugin.HsImport import Haskell.Ide.Engine.Plugin.Liquid import Haskell.Ide.Engine.Plugin.Package @@ -54,7 +52,6 @@ plugins includeExamples = pluginDescToIdePlugins allPlugins , brittanyDescriptor "brittany" , haddockDescriptor "haddock" -- , hareDescriptor "hare" - , hoogleDescriptor "hoogle" , hsimportDescriptor "hsimport" , liquidDescriptor "liquid" , packageDescriptor "package" @@ -132,9 +129,5 @@ run opts = do let plugins' = plugins (optExamplePlugin opts) -- launch the dispatcher. - if optJson opts then do - scheduler <- newScheduler plugins' initOpts - jsonStdioTransport scheduler - else do - scheduler <- newScheduler plugins' initOpts - lspStdioTransport scheduler origDir plugins' (optCaptureFile opts) + scheduler <- newScheduler plugins' initOpts + lspStdioTransport scheduler origDir plugins' (optCaptureFile opts) diff --git a/haskell-ide-engine.cabal b/haskell-ide-engine.cabal index 39e8f934d..981ca2472 100644 --- a/haskell-ide-engine.cabal +++ b/haskell-ide-engine.cabal @@ -33,7 +33,6 @@ library -- Haskell.Ide.Engine.Plugin.HaRe Haskell.Ide.Engine.Plugin.Haddock Haskell.Ide.Engine.Plugin.HfaAlign - Haskell.Ide.Engine.Plugin.Hoogle Haskell.Ide.Engine.Plugin.HsImport Haskell.Ide.Engine.Plugin.Liquid Haskell.Ide.Engine.Plugin.Package @@ -42,9 +41,9 @@ library Haskell.Ide.Engine.Plugin.Generic Haskell.Ide.Engine.Scheduler Haskell.Ide.Engine.Support.FromHaRe + Haskell.Ide.Engine.Support.Hoogle Haskell.Ide.Engine.Support.Fuzzy Haskell.Ide.Engine.Support.HieExtras - Haskell.Ide.Engine.Transport.JsonStdio Haskell.Ide.Engine.Transport.LspStdio Haskell.Ide.Engine.Types other-modules: Paths_haskell_ide_engine diff --git a/src/Haskell/Ide/Engine/LSP/Completions.hs b/src/Haskell/Ide/Engine/LSP/Completions.hs index ea322c768..4d53ed7cc 100644 --- a/src/Haskell/Ide/Engine/LSP/Completions.hs +++ b/src/Haskell/Ide/Engine/LSP/Completions.hs @@ -48,7 +48,7 @@ import qualified Language.Haskell.LSP.Types.Lens as J import qualified Haskell.Ide.Engine.Support.Fuzzy as Fuzzy -import qualified Haskell.Ide.Engine.Plugin.Hoogle +import qualified Haskell.Ide.Engine.Support.Hoogle as Hoogle import qualified Language.Haskell.LSP.VFS as VFS @@ -102,7 +102,7 @@ resolveCompletion :: WithSnippets -> J.CompletionItem -> IdeM J.CompletionItem resolveCompletion withSnippets origCompl = case fromJSON <$> origCompl ^. J.xdata of Just (J.Success compdata) -> do - mdocs <- Hoogle.infoCmd' $ hoogleQuery compdata + mdocs <- Hoogle.info $ hoogleQuery compdata let docText = case mdocs of Right x -> Just x _ -> Nothing diff --git a/src/Haskell/Ide/Engine/Options.hs b/src/Haskell/Ide/Engine/Options.hs index 43ce563ba..758361453 100644 --- a/src/Haskell/Ide/Engine/Options.hs +++ b/src/Haskell/Ide/Engine/Options.hs @@ -6,8 +6,6 @@ import Options.Applicative.Simple data GlobalOpts = GlobalOpts { optDebugOn :: Bool , optLogFile :: Maybe String - , optLsp :: Bool - , optJson :: Bool , projectRoot :: Maybe String , optBiosVerbose :: Bool , optCaptureFile :: Maybe FilePath @@ -27,12 +25,6 @@ globalOptsParser = GlobalOpts <> metavar "LOGFILE" <> help "File to log to, defaults to stdout" )) - <*> flag True True - ( long "lsp" - <> help "Enable the Language Server Protocol transport on STDIO (default)") - <*> switch - ( long "json" - <> help "Enable JSON transport on STDIO") <*> optional (strOption ( long "project-root" <> short 'r' diff --git a/src/Haskell/Ide/Engine/Plugin/Haddock.hs b/src/Haskell/Ide/Engine/Plugin/Haddock.hs index f3aa088c8..5af05e227 100644 --- a/src/Haskell/Ide/Engine/Plugin/Haddock.hs +++ b/src/Haskell/Ide/Engine/Plugin/Haddock.hs @@ -17,7 +17,7 @@ import GHC import GhcMonad import Haskell.Ide.Engine.MonadFunctions import Haskell.Ide.Engine.MonadTypes -import qualified Haskell.Ide.Engine.Plugin.Hoogle as Hoogle +import qualified Haskell.Ide.Engine.Support.Hoogle as Hoogle import Haskell.Ide.Engine.PluginUtils import Haskell.Ide.Engine.Support.HieExtras import HscTypes diff --git a/src/Haskell/Ide/Engine/Plugin/HsImport.hs b/src/Haskell/Ide/Engine/Plugin/HsImport.hs index 55d9a2b85..4d20ddb79 100644 --- a/src/Haskell/Ide/Engine/Plugin/HsImport.hs +++ b/src/Haskell/Ide/Engine/Plugin/HsImport.hs @@ -22,7 +22,7 @@ import qualified Haskell.Ide.Engine.Support.HieExtras as Hie import qualified Language.Haskell.LSP.Types as J import qualified Language.Haskell.LSP.Types.Lens as J import Haskell.Ide.Engine.PluginUtils -import qualified Haskell.Ide.Engine.Plugin.Hoogle +import qualified Haskell.Ide.Engine.Support.Hoogle as Hoogle import System.Directory import System.IO diff --git a/src/Haskell/Ide/Engine/Plugin/Package.hs b/src/Haskell/Ide/Engine/Plugin/Package.hs index b8e4f402e..3421d1444 100644 --- a/src/Haskell/Ide/Engine/Plugin/Package.hs +++ b/src/Haskell/Ide/Engine/Plugin/Package.hs @@ -7,7 +7,7 @@ module Haskell.Ide.Engine.Plugin.Package where import Haskell.Ide.Engine.MonadTypes -import qualified Haskell.Ide.Engine.Plugin.Hoogle as Hoogle +import qualified Haskell.Ide.Engine.Support.Hoogle as Hoogle import Haskell.Ide.Engine.PluginUtils import Haskell.Ide.Engine.Support.HieExtras as Hie import GHC.Generics diff --git a/src/Haskell/Ide/Engine/Plugin/Hoogle.hs b/src/Haskell/Ide/Engine/Support/Hoogle.hs similarity index 83% rename from src/Haskell/Ide/Engine/Plugin/Hoogle.hs rename to src/Haskell/Ide/Engine/Support/Hoogle.hs index 595aceda6..37da9ccd0 100644 --- a/src/Haskell/Ide/Engine/Plugin/Hoogle.hs +++ b/src/Haskell/Ide/Engine/Support/Hoogle.hs @@ -1,7 +1,7 @@ {-# LANGUAGE TupleSections #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} -module Haskell.Ide.Engine.Plugin.Hoogle where +module Haskell.Ide.Engine.Support.Hoogle where import Control.Monad.IO.Class import Control.Monad (join) @@ -22,27 +22,6 @@ import Text.HTML.TagSoup.Tree -- --------------------------------------------------------------------- -hoogleDescriptor :: PluginId -> PluginDescriptor -hoogleDescriptor plId = PluginDescriptor - { pluginId = plId - , pluginName = "hoogle" - , pluginDesc = - "Hoogle is a Haskell API search engine, which allows you to search " - <> "many standard Haskell libraries by either function name, or by approximate " - <> "type signature. " - , pluginCommands = - [ PluginCommand "info" "Look up the documentation for an identifier in the hoogle database" infoCmd - , PluginCommand "lookup" "Search the hoogle database with a string" lookupCmd - ] - , pluginCodeActionProvider = Nothing - , pluginDiagnosticProvider = Nothing - , pluginHoverProvider = Nothing - , pluginSymbolProvider = Nothing - , pluginFormattingProvider = Nothing - } - --- --------------------------------------------------------------------- - data HoogleError = NoDb | DbFail T.Text @@ -86,15 +65,8 @@ initializeHoogleDb = do else return Nothing -infoCmd :: CommandFunc T.Text T.Text -infoCmd = CmdSync $ \expr -> do - res <- liftToGhc $ bimap hoogleErrorToIdeError id <$> infoCmd' expr - return $ case res of - Left err -> IdeResultFail err - Right x -> IdeResultOk x - -infoCmd' :: T.Text -> IdeM (Either HoogleError T.Text) -infoCmd' expr = do +info :: T.Text -> IdeM (Either HoogleError T.Text) +info expr = do HoogleDb mdb <- get liftIO $ runHoogleQuery mdb expr $ \case [] -> Left NoResults @@ -116,8 +88,8 @@ renderTargetInfo t = -- If no result can be found for the identifier, a hoogle error is returned -- that can be shown to the client by converting it -- to an IdeError with 'hoogleErrorToIdeError'. -infoCmdFancyRender :: T.Text -> IdeM (Either HoogleError T.Text) -infoCmdFancyRender expr = do +infoFancyRender :: T.Text -> IdeM (Either HoogleError T.Text) +infoFancyRender expr = do HoogleDb mdb <- get liftIO $ runHoogleQuery mdb expr $ \case [] -> Left NoResults @@ -207,24 +179,14 @@ searchTargets f term = do ------------------------------------------------------------------------ --- | Lookup the given Text in the local Hoogle database. --- Is limited to collect at most ten matches. --- May fail with a HoogleError that can be shown to the user. -lookupCmd :: CommandFunc T.Text [T.Text] -lookupCmd = CmdSync $ \term -> do - res <- liftToGhc $ bimap hoogleErrorToIdeError id <$> lookupCmd' 10 term - return $ case res of - Left err -> IdeResultFail err - Right x -> IdeResultOk x - --- | Lookup the given Text in the local Hoogle database. --- Takes the first `n` matches. --- May fail with a HoogleError that can be shown to the user. -lookupCmd' :: Int -> T.Text -> IdeM (Either HoogleError [T.Text]) -lookupCmd' n term = do +-- | 'lookup' @n term@ looks up the given Text in the local Hoogle database. +-- Takes the first @n@ matches. + -- May fail with a HoogleError that can be shown to the user. +lookup :: Int -> T.Text -> IdeM (Either HoogleError [T.Text]) +lookup n term = do HoogleDb mdb <- get - liftIO $ runHoogleQuery mdb term - (Right . map (T.pack . targetResultDisplay False) . take n) + liftIO $ runHoogleQuery mdb term $ + Right . map (T.pack . targetResultDisplay False) . take n ------------------------------------------------------------------------ @@ -290,7 +252,7 @@ getDocsForName name pkg modName' = do <> " module:" <> modName <> " is:exact" debugm $ "hoogle query: " ++ T.unpack query - res <- infoCmdFancyRender query + res <- infoFancyRender query case res of Right x -> return $ Just x Left _ -> return Nothing diff --git a/src/Haskell/Ide/Engine/Transport/JsonStdio.hs b/src/Haskell/Ide/Engine/Transport/JsonStdio.hs deleted file mode 100644 index dd8db6154..000000000 --- a/src/Haskell/Ide/Engine/Transport/JsonStdio.hs +++ /dev/null @@ -1,127 +0,0 @@ -{-# LANGUAGE DeriveAnyClass #-} -{-# LANGUAGE DeriveGeneric #-} -{-# LANGUAGE DuplicateRecordFields #-} -{-# LANGUAGE LambdaCase #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE RankNTypes #-} - -module Haskell.Ide.Engine.Transport.JsonStdio - ( - jsonStdioTransport - ) where - -import Control.Concurrent.Async -import Control.Concurrent.STM.TChan -import qualified Control.Exception as E -import Control.Monad -import Control.Monad.STM -import Control.Monad.IO.Class -import qualified Data.Aeson as J -import qualified Data.ByteString.Builder as B -import qualified Data.ByteString.Lazy.Char8 as B -import qualified Data.Text as T -import GHC.Generics -import Haskell.Ide.Engine.PluginsIdeMonads -import qualified Haskell.Ide.Engine.Scheduler as Scheduler -import Haskell.Ide.Engine.Types -import qualified Language.Haskell.LSP.Types as J -import System.Exit -import System.IO -import qualified System.Log.Logger as L - --- --------------------------------------------------------------------- - -{-# ANN module ("hlint: ignore Eta reduce" :: String) #-} -{-# ANN module ("hlint: ignore Redundant do" :: String) #-} - --- --------------------------------------------------------------------- - -jsonStdioTransport :: Scheduler.Scheduler IO -> IO () -jsonStdioTransport scheduler = do - run scheduler >>= \case - 0 -> exitSuccess - c -> exitWith . ExitFailure $ c - --- --------------------------------------------------------------------- - -data ReactorInput = - ReactorInput - { reqId :: Int - , plugin :: T.Text - , command :: T.Text - , context :: Maybe J.Uri - , arg :: J.Value - } deriving (Eq, Show, Generic, J.ToJSON, J.FromJSON) - -data ReactorOutput = ReactorOutput - { _resId :: Int - , _response :: J.Value - } deriving (Eq, Show, Generic, J.ToJSON, J.FromJSON) - -run :: Scheduler.Scheduler IO -> IO Int -run scheduler = flip E.catches handlers $ do - flip E.finally finalProc $ do - rout <- atomically newTChan :: IO (TChan ReactorOutput) - - let race3_ a b c = race_ a (race_ b c) - - let errorHandler lid _ e = liftIO $ hPutStrLn stderr $ "Got an error for request " ++ show lid ++ ": " ++ T.unpack e - callbackHandler callback x = callback x - - race3_ (Scheduler.runScheduler scheduler errorHandler callbackHandler Nothing) - (outWriter rout) - (reactor rout) - - return 0 - - where - handlers = [ E.Handler ioExcept - , E.Handler someExcept - ] - finalProc = L.removeAllHandlers - ioExcept (e :: E.IOException) = print e >> return 1 - someExcept (e :: E.SomeException) = print e >> return 1 - - outWriter rout = forever $ do - out <- atomically $ readTChan rout - B.putStr $ J.encode out - putChar '\STX' - - reactor rout = - let sendResponse rid resp = atomically $ writeTChan rout (ReactorOutput rid resp) in - forever $ do - mreq <- getNextReq - case mreq of - Nothing -> return() - Just req -> do - let preq = GReq 0 "" (context req) Nothing (Just $ J.IdInt rid) (liftIO . callback) (toDynJSON (Nothing :: Maybe ())) - $ runPluginCommand (plugin req) (command req) (arg req) - rid = reqId req - callback = sendResponse rid . dynToJSON - Scheduler.sendRequest scheduler preq - -getNextReq :: IO (Maybe ReactorInput) -getNextReq = do - mbs <- fmap B.toLazyByteString <$> readReqByteString - case mbs of - -- EOF - Nothing -> return Nothing - Just bs -> case J.eitherDecode bs of - Left err -> do - hPutStrLn stderr $ "Couldn't parse" ++ B.unpack bs ++ "\n got error" ++ show err - getNextReq - Right req -> return $ Just req - where - readReqByteString = do - eof <- isEOF - if eof then - return Nothing - else do - char <- getChar - if char == '\STX' then - return $ Just "" - else do - rest <- readReqByteString - let cur = B.charUtf8 char - return $ Just $ maybe cur (cur <>) rest diff --git a/src/Haskell/Ide/Engine/Transport/LspStdio.hs b/src/Haskell/Ide/Engine/Transport/LspStdio.hs index 27906e96d..a8d52e6bb 100644 --- a/src/Haskell/Ide/Engine/Transport/LspStdio.hs +++ b/src/Haskell/Ide/Engine/Transport/LspStdio.hs @@ -49,7 +49,7 @@ import Haskell.Ide.Engine.MonadTypes import qualified Haskell.Ide.Engine.Plugin.ApplyRefact as ApplyRefact import Haskell.Ide.Engine.Plugin.Base -- import qualified Haskell.Ide.Engine.Plugin.HaRe as HaRe -import qualified Haskell.Ide.Engine.Plugin.Hoogle as Hoogle +import qualified Haskell.Ide.Engine.Support.Hoogle as Hoogle import Haskell.Ide.Engine.PluginUtils import qualified Haskell.Ide.Engine.Scheduler as Scheduler import qualified Haskell.Ide.Engine.Support.HieExtras as Hie diff --git a/test/unit/HooglePluginSpec.hs b/test/unit/HooglePluginSpec.hs index ca4fc8837..f399ecdcd 100644 --- a/test/unit/HooglePluginSpec.hs +++ b/test/unit/HooglePluginSpec.hs @@ -5,7 +5,7 @@ module HooglePluginSpec where import Control.Monad import Data.Maybe import Haskell.Ide.Engine.MonadTypes -import Haskell.Ide.Engine.Plugin.Hoogle +import Haskell.Ide.Engine.Support.Hoogle import Hoogle import System.Directory import Test.Hspec @@ -23,7 +23,7 @@ spec = do -- --------------------------------------------------------------------- testPlugins :: IdePlugins -testPlugins = pluginDescToIdePlugins [hoogleDescriptor "hoogle"] +testPlugins = pluginDescToIdePlugins [] dispatchRequestP :: IdeGhcM a -> IO a dispatchRequestP = runIGM testPlugins @@ -46,13 +46,13 @@ hoogleSpec = do describe "hoogle plugin commands(new plugin api)" $ do it "runs the info command" $ do - let req = liftToGhc $ infoCmd' "head" + let req = liftToGhc $ info "head" r <- dispatchRequestP $ initializeHoogleDb >> req r `shouldBe` Right "```haskell\nhead :: [a] -> a\n```\nExtract the first element of a list, which must be non-empty.\n\n[More info](https://hackage.haskell.org/package/base/docs/Prelude.html#v:head)" -- --------------------------------- it "runs the lookup command" $ do - let req = liftToGhc $ lookupCmd' 1 "[a] -> a" + let req = liftToGhc $ Haskell.Ide.Engine.Support.Hoogle.lookup 1 "[a] -> a" r <- dispatchRequestP $ initializeHoogleDb >> req r `shouldBe` Right ["Prelude head :: [a] -> a"] From eac07097fa88b1a2c5a0c5f61ceadb20e0709a59 Mon Sep 17 00:00:00 2001 From: Luke Lau Date: Sat, 21 Dec 2019 23:26:49 +0000 Subject: [PATCH 2/5] Rename LspStdio to Server, move out LSP modules --- app/MainHie.hs | 4 ++-- haskell-ide-engine.cabal | 8 ++++---- src/Haskell/Ide/Engine/{LSP => }/CodeActions.hs | 4 ++-- src/Haskell/Ide/Engine/{LSP => }/Completions.hs | 2 +- src/Haskell/Ide/Engine/{LSP => }/Reactor.hs | 2 +- .../Engine/{Transport/LspStdio.hs => Server.hs} | 14 +++++++------- 6 files changed, 17 insertions(+), 17 deletions(-) rename src/Haskell/Ide/Engine/{LSP => }/CodeActions.hs (97%) rename src/Haskell/Ide/Engine/{LSP => }/Completions.hs (99%) rename src/Haskell/Ide/Engine/{LSP => }/Reactor.hs (99%) rename src/Haskell/Ide/Engine/{Transport/LspStdio.hs => Server.hs} (99%) diff --git a/app/MainHie.hs b/app/MainHie.hs index eda552266..ce2fefb33 100644 --- a/app/MainHie.hs +++ b/app/MainHie.hs @@ -9,7 +9,7 @@ import Haskell.Ide.Engine.MonadFunctions import Haskell.Ide.Engine.MonadTypes import Haskell.Ide.Engine.Options import Haskell.Ide.Engine.Scheduler -import Haskell.Ide.Engine.Transport.LspStdio +import Haskell.Ide.Engine.Server import qualified Language.Haskell.LSP.Core as Core import Options.Applicative.Simple import qualified Paths_haskell_ide_engine as Meta @@ -130,4 +130,4 @@ run opts = do -- launch the dispatcher. scheduler <- newScheduler plugins' initOpts - lspStdioTransport scheduler origDir plugins' (optCaptureFile opts) + server scheduler origDir plugins' (optCaptureFile opts) diff --git a/haskell-ide-engine.cabal b/haskell-ide-engine.cabal index 981ca2472..c5483ca45 100644 --- a/haskell-ide-engine.cabal +++ b/haskell-ide-engine.cabal @@ -20,10 +20,10 @@ flag pedantic library hs-source-dirs: src exposed-modules: Haskell.Ide.Engine.Channel - Haskell.Ide.Engine.LSP.CodeActions - Haskell.Ide.Engine.LSP.Completions + Haskell.Ide.Engine.CodeActions + Haskell.Ide.Engine.Completions Haskell.Ide.Engine.Plugin.Base - Haskell.Ide.Engine.LSP.Reactor + Haskell.Ide.Engine.Reactor Haskell.Ide.Engine.Options Haskell.Ide.Engine.Plugin.ApplyRefact Haskell.Ide.Engine.Plugin.Brittany @@ -44,7 +44,7 @@ library Haskell.Ide.Engine.Support.Hoogle Haskell.Ide.Engine.Support.Fuzzy Haskell.Ide.Engine.Support.HieExtras - Haskell.Ide.Engine.Transport.LspStdio + Haskell.Ide.Engine.Server Haskell.Ide.Engine.Types other-modules: Paths_haskell_ide_engine build-depends: Cabal >= 1.22 diff --git a/src/Haskell/Ide/Engine/LSP/CodeActions.hs b/src/Haskell/Ide/Engine/CodeActions.hs similarity index 97% rename from src/Haskell/Ide/Engine/LSP/CodeActions.hs rename to src/Haskell/Ide/Engine/CodeActions.hs index 1753d5f48..3939ae5d3 100644 --- a/src/Haskell/Ide/Engine/LSP/CodeActions.hs +++ b/src/Haskell/Ide/Engine/CodeActions.hs @@ -3,7 +3,7 @@ {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE FlexibleContexts #-} -module Haskell.Ide.Engine.LSP.CodeActions where +module Haskell.Ide.Engine.CodeActions where import Control.Lens import Control.Monad.Reader @@ -11,7 +11,7 @@ import qualified Data.Aeson as J import Data.Maybe import Data.Foldable import qualified GHC.Generics as G -import Haskell.Ide.Engine.LSP.Reactor +import Haskell.Ide.Engine.Reactor import Haskell.Ide.Engine.Types import qualified Language.Haskell.LSP.Core as Core import qualified Language.Haskell.LSP.Types as J diff --git a/src/Haskell/Ide/Engine/LSP/Completions.hs b/src/Haskell/Ide/Engine/Completions.hs similarity index 99% rename from src/Haskell/Ide/Engine/LSP/Completions.hs rename to src/Haskell/Ide/Engine/Completions.hs index 4d53ed7cc..c1234bb87 100644 --- a/src/Haskell/Ide/Engine/LSP/Completions.hs +++ b/src/Haskell/Ide/Engine/Completions.hs @@ -1,7 +1,7 @@ {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} -module Haskell.Ide.Engine.LSP.Completions +module Haskell.Ide.Engine.Completions ( WithSnippets(..) , getCompletions , resolveCompletion diff --git a/src/Haskell/Ide/Engine/LSP/Reactor.hs b/src/Haskell/Ide/Engine/Reactor.hs similarity index 99% rename from src/Haskell/Ide/Engine/LSP/Reactor.hs rename to src/Haskell/Ide/Engine/Reactor.hs index f1e8dfdaf..ec2f14eb7 100644 --- a/src/Haskell/Ide/Engine/LSP/Reactor.hs +++ b/src/Haskell/Ide/Engine/Reactor.hs @@ -1,7 +1,7 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} -module Haskell.Ide.Engine.LSP.Reactor +module Haskell.Ide.Engine.Reactor ( R , runReactor , reactorSend diff --git a/src/Haskell/Ide/Engine/Transport/LspStdio.hs b/src/Haskell/Ide/Engine/Server.hs similarity index 99% rename from src/Haskell/Ide/Engine/Transport/LspStdio.hs rename to src/Haskell/Ide/Engine/Server.hs index a8d52e6bb..185ca340c 100644 --- a/src/Haskell/Ide/Engine/Transport/LspStdio.hs +++ b/src/Haskell/Ide/Engine/Server.hs @@ -10,9 +10,9 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE PartialTypeSignatures #-} -module Haskell.Ide.Engine.Transport.LspStdio +module Haskell.Ide.Engine.Server ( - lspStdioTransport + server ) where import Control.Concurrent @@ -41,9 +41,9 @@ import qualified Data.Yaml as Yaml import Haskell.Ide.Engine.Cradle (findLocalCradle, cradleDisplay) import Haskell.Ide.Engine.Config import qualified Haskell.Ide.Engine.Ghc as HIE -import Haskell.Ide.Engine.LSP.CodeActions -import qualified Haskell.Ide.Engine.LSP.Completions as Completions -import Haskell.Ide.Engine.LSP.Reactor +import Haskell.Ide.Engine.CodeActions +import qualified Haskell.Ide.Engine.Completions as Completions +import Haskell.Ide.Engine.Reactor import Haskell.Ide.Engine.MonadFunctions import Haskell.Ide.Engine.MonadTypes import qualified Haskell.Ide.Engine.Plugin.ApplyRefact as ApplyRefact @@ -76,13 +76,13 @@ import GHC.Conc {-# ANN module ("hlint: ignore Use tuple-section" :: String) #-} -- --------------------------------------------------------------------- -lspStdioTransport +server :: Scheduler.Scheduler R -> FilePath -> IdePlugins -> Maybe FilePath -> IO () -lspStdioTransport scheduler origDir plugins captureFp = do +server scheduler origDir plugins captureFp = do run scheduler origDir plugins captureFp >>= \case 0 -> exitSuccess c -> exitWith . ExitFailure $ c From d3bce6570a800eff790206654f63869cf05a5137 Mon Sep 17 00:00:00 2001 From: Luke Lau Date: Sat, 21 Dec 2019 23:27:09 +0000 Subject: [PATCH 3/5] Remove unused Liquid haskell commands --- src/Haskell/Ide/Engine/Plugin/Liquid.hs | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/src/Haskell/Ide/Engine/Plugin/Liquid.hs b/src/Haskell/Ide/Engine/Plugin/Liquid.hs index 266931bd6..1888a3001 100644 --- a/src/Haskell/Ide/Engine/Plugin/Liquid.hs +++ b/src/Haskell/Ide/Engine/Plugin/Liquid.hs @@ -35,10 +35,7 @@ liquidDescriptor plId = PluginDescriptor { pluginId = plId , pluginName = "Liquid Haskell" , pluginDesc = "Integration with Liquid Haskell" - , pluginCommands = - [ PluginCommand "sayHello" "say hello" sayHelloCmd - , PluginCommand "sayHelloTo" "say hello to the passed in param" sayHelloToCmd - ] + , pluginCommands = [] , pluginCodeActionProvider = Nothing , pluginDiagnosticProvider = Just (DiagnosticProvider (S.singleton DiagnosticOnSave) @@ -50,24 +47,6 @@ liquidDescriptor plId = PluginDescriptor -- --------------------------------------------------------------------- -sayHelloCmd :: CommandFunc () T.Text -sayHelloCmd = CmdSync $ \_ -> return (IdeResultOk sayHello) - -sayHelloToCmd :: CommandFunc T.Text T.Text -sayHelloToCmd = CmdSync $ \n -> do - r <- liftIO $ sayHelloTo n - return $ IdeResultOk r - --- --------------------------------------------------------------------- - -sayHello :: T.Text -sayHello = "hello from ExamplePlugin2" - -sayHelloTo :: T.Text -> IO T.Text -sayHelloTo n = return $ "hello " <> n <> " from ExamplePlugin2" - --- --------------------------------------------------------------------- - data LiquidJson = LJ { status :: T.Text From aa0f0c5ec90b1f030af4fa1201ddb3f88759cc1f Mon Sep 17 00:00:00 2001 From: Luke Lau Date: Sat, 21 Dec 2019 23:38:03 +0000 Subject: [PATCH 4/5] Remove Base plugin --- app/HieWrapper.hs | 6 +- app/MainHie.hs | 7 +- haskell-ide-engine.cabal | 2 +- src/Haskell/Ide/Engine/Server.hs | 4 +- .../Ide/Engine/{Plugin/Base.hs => Version.hs} | 87 +++---------------- test/dispatcher/Main.hs | 2 - test/wrapper/HieWrapper.hs | 2 +- 7 files changed, 20 insertions(+), 90 deletions(-) rename src/Haskell/Ide/Engine/{Plugin/Base.hs => Version.hs} (53%) diff --git a/app/HieWrapper.hs b/app/HieWrapper.hs index ef6ae24f7..c99464d21 100644 --- a/app/HieWrapper.hs +++ b/app/HieWrapper.hs @@ -13,7 +13,7 @@ import HIE.Bios import Haskell.Ide.Engine.MonadFunctions import Haskell.Ide.Engine.Cradle (findLocalCradle) import Haskell.Ide.Engine.Options -import Haskell.Ide.Engine.Plugin.Base +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 @@ -44,7 +44,7 @@ main = do -- Parse the options and run (global, ()) <- simpleOptions - version + hieVersion "hie-wrapper - Launch the appropriate haskell-ide-engine for a given project" "" (numericVersion <*> compiler <*> globalOptsParser) @@ -68,7 +68,7 @@ run opts = do progName <- getProgName - logm $ "run entered for hie-wrapper(" ++ progName ++ ") " ++ version + logm $ "run entered for hie-wrapper(" ++ progName ++ ") " ++ hieVersion d <- getCurrentDirectory logm $ "Current directory:" ++ d logm $ "Operating system:" ++ os diff --git a/app/MainHie.hs b/app/MainHie.hs index ce2fefb33..e4f677975 100644 --- a/app/MainHie.hs +++ b/app/MainHie.hs @@ -10,6 +10,7 @@ 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 @@ -23,7 +24,6 @@ import System.IO -- plugins import Haskell.Ide.Engine.Plugin.ApplyRefact -import Haskell.Ide.Engine.Plugin.Base import Haskell.Ide.Engine.Plugin.Brittany import Haskell.Ide.Engine.Plugin.Example2 import Haskell.Ide.Engine.Plugin.Bios @@ -48,7 +48,6 @@ plugins includeExamples = pluginDescToIdePlugins allPlugins else basePlugins basePlugins = [ applyRefactDescriptor "applyrefact" - , baseDescriptor "base" , brittanyDescriptor "brittany" , haddockDescriptor "haddock" -- , hareDescriptor "hare" @@ -85,7 +84,7 @@ main = do -- Parse the options and run (global, ()) <- simpleOptions - version + hieVersion "haskell-ide-engine - Provide a common engine to power any Haskell IDE" "" (numericVersion <*> compiler <*> globalOptsParser) @@ -111,7 +110,7 @@ run opts = do maybe (pure ()) setCurrentDirectory $ projectRoot opts progName <- getProgName - logm $ "Run entered for HIE(" ++ progName ++ ") " ++ version + logm $ "Run entered for HIE(" ++ progName ++ ") " ++ hieVersion logm $ "Current directory:" ++ origDir args <- getArgs logm $ "args:" ++ show args diff --git a/haskell-ide-engine.cabal b/haskell-ide-engine.cabal index c5483ca45..7c17e714e 100644 --- a/haskell-ide-engine.cabal +++ b/haskell-ide-engine.cabal @@ -22,7 +22,6 @@ library exposed-modules: Haskell.Ide.Engine.Channel Haskell.Ide.Engine.CodeActions Haskell.Ide.Engine.Completions - Haskell.Ide.Engine.Plugin.Base Haskell.Ide.Engine.Reactor Haskell.Ide.Engine.Options Haskell.Ide.Engine.Plugin.ApplyRefact @@ -46,6 +45,7 @@ library Haskell.Ide.Engine.Support.HieExtras Haskell.Ide.Engine.Server Haskell.Ide.Engine.Types + Haskell.Ide.Engine.Version other-modules: Paths_haskell_ide_engine build-depends: Cabal >= 1.22 , Diff diff --git a/src/Haskell/Ide/Engine/Server.hs b/src/Haskell/Ide/Engine/Server.hs index 185ca340c..be7634abc 100644 --- a/src/Haskell/Ide/Engine/Server.hs +++ b/src/Haskell/Ide/Engine/Server.hs @@ -47,7 +47,6 @@ import Haskell.Ide.Engine.Reactor import Haskell.Ide.Engine.MonadFunctions import Haskell.Ide.Engine.MonadTypes import qualified Haskell.Ide.Engine.Plugin.ApplyRefact as ApplyRefact -import Haskell.Ide.Engine.Plugin.Base -- import qualified Haskell.Ide.Engine.Plugin.HaRe as HaRe import qualified Haskell.Ide.Engine.Support.Hoogle as Hoogle import Haskell.Ide.Engine.PluginUtils @@ -55,6 +54,7 @@ import qualified Haskell.Ide.Engine.Scheduler as Scheduler import qualified Haskell.Ide.Engine.Support.HieExtras as Hie import Haskell.Ide.Engine.Types import qualified Haskell.Ide.Engine.Plugin.Bios as BIOS +import Haskell.Ide.Engine.Version import qualified Language.Haskell.LSP.Control as CTRL import qualified Language.Haskell.LSP.Core as Core import Language.Haskell.LSP.Diagnostics @@ -395,7 +395,7 @@ reactor inp diagIn = do reactorSend $ ReqRegisterCapability $ fmServerRegisterCapabilityRequest rid registrations reactorSend $ NotLogMessage $ - fmServerLogMessageNotification J.MtLog $ "Using hie version: " <> T.pack version + fmServerLogMessageNotification J.MtLog $ "Using hie version: " <> T.pack hieVersion lspRootDir <- asksLspFuncs Core.rootPath currentDir <- liftIO getCurrentDirectory diff --git a/src/Haskell/Ide/Engine/Plugin/Base.hs b/src/Haskell/Ide/Engine/Version.hs similarity index 53% rename from src/Haskell/Ide/Engine/Plugin/Base.hs rename to src/Haskell/Ide/Engine/Version.hs index 1a7564c0d..ead3f6f9f 100644 --- a/src/Haskell/Ide/Engine/Plugin/Base.hs +++ b/src/Haskell/Ide/Engine/Version.hs @@ -1,93 +1,26 @@ -{-# LANGUAGE CPP #-} -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE PartialTypeSignatures #-} -{-# LANGUAGE TemplateHaskell #-} -module Haskell.Ide.Engine.Plugin.Base where +{-# LANGUAGE CPP, TemplateHaskell, OverloadedStrings #-} +-- | Information and display strings for HIE's version +-- and the current project's version +module Haskell.Ide.Engine.Version where import Control.Exception -import Data.Aeson -import Data.Foldable -import qualified Data.Map as Map import Data.Maybe -import qualified Data.Text as T -import qualified Data.Versions as V import Development.GitRev (gitCommitCount) import Distribution.System (buildArch) import Distribution.Text (display) -import Haskell.Ide.Engine.MonadTypes +import Options.Applicative.Simple (simpleVersion) import Haskell.Ide.Engine.Cradle (isStackCradle) import qualified HIE.Bios.Types as BIOS -import Options.Applicative.Simple (simpleVersion) import qualified Paths_haskell_ide_engine as Meta - +import qualified System.Log.Logger as L +import qualified Data.Text as T +import qualified Data.Versions as V import System.Directory import System.Info import System.Process -import qualified System.Log.Logger as L - --- --------------------------------------------------------------------- - -baseDescriptor :: PluginId -> PluginDescriptor -baseDescriptor plId = PluginDescriptor - { pluginId = plId - , pluginName = "HIE Base" - , pluginDesc = "Commands for HIE itself" - , pluginCommands = - [ PluginCommand "version" "return HIE version" versionCmd - , PluginCommand "plugins" "list available plugins" pluginsCmd - , PluginCommand "commands" "list available commands for a given plugin" commandsCmd - , PluginCommand "commandDetail" "list parameters required for a given command" commandDetailCmd - ] - , pluginCodeActionProvider = Nothing - , pluginDiagnosticProvider = Nothing - , pluginHoverProvider = Nothing - , pluginSymbolProvider = Nothing - , pluginFormattingProvider = Nothing - } - --- --------------------------------------------------------------------- - -versionCmd :: CommandFunc () T.Text -versionCmd = CmdSync $ \_ -> return $ IdeResultOk (T.pack version) - -pluginsCmd :: CommandFunc () IdePlugins -pluginsCmd = CmdSync $ \_ -> - IdeResultOk <$> getPlugins - -commandsCmd :: CommandFunc T.Text [CommandName] -commandsCmd = CmdSync $ \p -> do - IdePlugins plugins <- getPlugins - case Map.lookup p plugins of - Nothing -> return $ IdeResultFail $ IdeError - { ideCode = UnknownPlugin - , ideMessage = "Can't find plugin:" <> p - , ideInfo = toJSON p - } - Just pl -> return $ IdeResultOk $ map commandName $ pluginCommands pl - -commandDetailCmd :: CommandFunc (T.Text, T.Text) T.Text -commandDetailCmd = CmdSync $ \(p,command) -> do - IdePlugins plugins <- getPlugins - case Map.lookup p plugins of - Nothing -> return $ IdeResultFail $ IdeError - { ideCode = UnknownPlugin - , ideMessage = "Can't find plugin:" <> p - , ideInfo = toJSON p - } - Just pl -> case find (\cmd -> command == commandName cmd) (pluginCommands pl) of - Nothing -> return $ IdeResultFail $ IdeError - { ideCode = UnknownCommand - , ideMessage = "Can't find command:" <> command - , ideInfo = toJSON command - } - Just detail -> return $ IdeResultOk (commandDesc detail) - --- --------------------------------------------------------------------- -version :: String -version = +hieVersion :: String +hieVersion = let commitCount = $gitCommitCount in concat $ concat [ [$(simpleVersion Meta.version)] diff --git a/test/dispatcher/Main.hs b/test/dispatcher/Main.hs index 11f800c2a..63a195299 100644 --- a/test/dispatcher/Main.hs +++ b/test/dispatcher/Main.hs @@ -31,7 +31,6 @@ import System.IO -- plugins import Haskell.Ide.Engine.Plugin.ApplyRefact -import Haskell.Ide.Engine.Plugin.Base import Haskell.Ide.Engine.Plugin.Example2 -- import Haskell.Ide.Engine.Plugin.HaRe import Haskell.Ide.Engine.Plugin.Bios @@ -66,7 +65,6 @@ plugins = pluginDescToIdePlugins [applyRefactDescriptor "applyrefact" ,example2Descriptor "eg2" ,biosDescriptor "bios" - ,baseDescriptor "base" ] startServer :: IO (Scheduler IO, TChan LogVal, ThreadId) diff --git a/test/wrapper/HieWrapper.hs b/test/wrapper/HieWrapper.hs index e66af5e15..ef8cb4aa5 100644 --- a/test/wrapper/HieWrapper.hs +++ b/test/wrapper/HieWrapper.hs @@ -2,7 +2,7 @@ module Main where import Control.Monad.IO.Class (liftIO) import Haskell.Ide.Engine.Cradle (findLocalCradle) -import Haskell.Ide.Engine.Plugin.Base +import Haskell.Ide.Engine.Version import Test.Hspec import System.Directory import System.FilePath From c38fff55befe315200a5a0c57222ac8c56e9beca Mon Sep 17 00:00:00 2001 From: Luke Lau Date: Sun, 22 Dec 2019 14:46:24 +0000 Subject: [PATCH 5/5] Fix formatting --- src/Haskell/Ide/Engine/Support/Hoogle.hs | 2 +- src/Haskell/Ide/Engine/Version.hs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Haskell/Ide/Engine/Support/Hoogle.hs b/src/Haskell/Ide/Engine/Support/Hoogle.hs index 37da9ccd0..b7d94f582 100644 --- a/src/Haskell/Ide/Engine/Support/Hoogle.hs +++ b/src/Haskell/Ide/Engine/Support/Hoogle.hs @@ -181,7 +181,7 @@ searchTargets f term = do -- | 'lookup' @n term@ looks up the given Text in the local Hoogle database. -- Takes the first @n@ matches. - -- May fail with a HoogleError that can be shown to the user. +-- May fail with a HoogleError that can be shown to the user. lookup :: Int -> T.Text -> IdeM (Either HoogleError [T.Text]) lookup n term = do HoogleDb mdb <- get diff --git a/src/Haskell/Ide/Engine/Version.hs b/src/Haskell/Ide/Engine/Version.hs index ead3f6f9f..d81df88cf 100644 --- a/src/Haskell/Ide/Engine/Version.hs +++ b/src/Haskell/Ide/Engine/Version.hs @@ -1,4 +1,6 @@ -{-# LANGUAGE CPP, TemplateHaskell, OverloadedStrings #-} +{-# LANGUAGE CPP #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE OverloadedStrings #-} -- | Information and display strings for HIE's version -- and the current project's version module Haskell.Ide.Engine.Version where