{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE OverloadedStrings     #-}

-- | Exposes the ghcide features as an HLS plugin
module Development.IDE.Plugin.HLS.GhcIde
  (
    descriptors
  , Log(..)
  ) where
import           Control.Monad.IO.Class
import           Development.IDE
import           Development.IDE.LSP.HoverDefinition
import qualified Development.IDE.LSP.Notifications   as Notifications
import           Development.IDE.LSP.Outline
import qualified Development.IDE.Plugin.CodeAction   as CodeAction
import qualified Development.IDE.Plugin.Completions  as Completions
import qualified Development.IDE.Plugin.TypeLenses   as TypeLenses
import           Ide.Types
import           Language.LSP.Server                 (LspM)
import           Language.LSP.Types
import           Text.Regex.TDFA.Text                ()

data Log
  = LogNotifications Notifications.Log
  | LogCompletions Completions.Log
  | LogTypeLenses TypeLenses.Log
  deriving Int -> Log -> ShowS
[Log] -> ShowS
Log -> String
(Int -> Log -> ShowS)
-> (Log -> String) -> ([Log] -> ShowS) -> Show Log
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Log] -> ShowS
$cshowList :: [Log] -> ShowS
show :: Log -> String
$cshow :: Log -> String
showsPrec :: Int -> Log -> ShowS
$cshowsPrec :: Int -> Log -> ShowS
Show

instance Pretty Log where
  pretty :: Log -> Doc ann
pretty = \case
    LogNotifications Log
log -> Log -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Log
log
    LogCompletions Log
log   -> Log -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Log
log
    LogTypeLenses Log
log    -> Log -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Log
log

descriptors :: Recorder (WithPriority Log) -> [PluginDescriptor IdeState]
descriptors :: Recorder (WithPriority Log) -> [PluginDescriptor IdeState]
descriptors Recorder (WithPriority Log)
recorder =
  [ PluginId -> PluginDescriptor IdeState
descriptor PluginId
"ghcide-hover-and-symbols",
    PluginId -> PluginDescriptor IdeState
CodeAction.iePluginDescriptor PluginId
"ghcide-code-actions-imports-exports",
    PluginId -> PluginDescriptor IdeState
CodeAction.typeSigsPluginDescriptor PluginId
"ghcide-code-actions-type-signatures",
    PluginId -> PluginDescriptor IdeState
CodeAction.bindingsPluginDescriptor PluginId
"ghcide-code-actions-bindings",
    PluginId -> PluginDescriptor IdeState
CodeAction.fillHolePluginDescriptor PluginId
"ghcide-code-actions-fill-holes",
    Recorder (WithPriority Log)
-> PluginId -> PluginDescriptor IdeState
Completions.descriptor ((Log -> Log)
-> Recorder (WithPriority Log) -> Recorder (WithPriority Log)
forall a b.
(a -> b) -> Recorder (WithPriority b) -> Recorder (WithPriority a)
cmapWithPrio Log -> Log
LogCompletions Recorder (WithPriority Log)
recorder) PluginId
"ghcide-completions",
    Recorder (WithPriority Log)
-> PluginId -> PluginDescriptor IdeState
TypeLenses.descriptor ((Log -> Log)
-> Recorder (WithPriority Log) -> Recorder (WithPriority Log)
forall a b.
(a -> b) -> Recorder (WithPriority b) -> Recorder (WithPriority a)
cmapWithPrio Log -> Log
LogTypeLenses Recorder (WithPriority Log)
recorder) PluginId
"ghcide-type-lenses",
    Recorder (WithPriority Log)
-> PluginId -> PluginDescriptor IdeState
Notifications.descriptor ((Log -> Log)
-> Recorder (WithPriority Log) -> Recorder (WithPriority Log)
forall a b.
(a -> b) -> Recorder (WithPriority b) -> Recorder (WithPriority a)
cmapWithPrio Log -> Log
LogNotifications Recorder (WithPriority Log)
recorder) PluginId
"ghcide-core"
  ]

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

descriptor :: PluginId -> PluginDescriptor IdeState
descriptor :: PluginId -> PluginDescriptor IdeState
descriptor PluginId
plId = (PluginId -> PluginDescriptor IdeState
forall ideState. PluginId -> PluginDescriptor ideState
defaultPluginDescriptor PluginId
plId)
  { pluginHandlers :: PluginHandlers IdeState
pluginHandlers = SClientMethod 'TextDocumentHover
-> PluginMethodHandler IdeState 'TextDocumentHover
-> PluginHandlers IdeState
forall (m :: Method 'FromClient 'Request) ideState.
PluginMethod m =>
SClientMethod m
-> PluginMethodHandler ideState m -> PluginHandlers ideState
mkPluginHandler SClientMethod 'TextDocumentHover
STextDocumentHover PluginMethodHandler IdeState 'TextDocumentHover
forall c.
IdeState
-> PluginId
-> HoverParams
-> LspM c (Either ResponseError (Maybe Hover))
hover'
                  PluginHandlers IdeState
-> PluginHandlers IdeState -> PluginHandlers IdeState
forall a. Semigroup a => a -> a -> a
<> SClientMethod 'TextDocumentDocumentSymbol
-> PluginMethodHandler IdeState 'TextDocumentDocumentSymbol
-> PluginHandlers IdeState
forall (m :: Method 'FromClient 'Request) ideState.
PluginMethod m =>
SClientMethod m
-> PluginMethodHandler ideState m -> PluginHandlers ideState
mkPluginHandler SClientMethod 'TextDocumentDocumentSymbol
STextDocumentDocumentSymbol PluginMethodHandler IdeState 'TextDocumentDocumentSymbol
forall c.
IdeState
-> PluginId
-> DocumentSymbolParams
-> LspM
     c
     (Either
        ResponseError (List DocumentSymbol |? List SymbolInformation))
symbolsProvider,
    pluginConfigDescriptor :: ConfigDescriptor
pluginConfigDescriptor = ConfigDescriptor
defaultConfigDescriptor {configEnableGenericConfig :: Bool
configEnableGenericConfig = Bool
False}
  }

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

hover' :: IdeState -> PluginId -> HoverParams  -> LspM c (Either ResponseError (Maybe Hover))
hover' :: IdeState
-> PluginId
-> HoverParams
-> LspM c (Either ResponseError (Maybe Hover))
hover' IdeState
ideState PluginId
_ HoverParams{Maybe ProgressToken
TextDocumentIdentifier
Position
$sel:_textDocument:HoverParams :: HoverParams -> TextDocumentIdentifier
$sel:_position:HoverParams :: HoverParams -> Position
$sel:_workDoneToken:HoverParams :: HoverParams -> Maybe ProgressToken
_workDoneToken :: Maybe ProgressToken
_position :: Position
_textDocument :: TextDocumentIdentifier
..} = do
    IO () -> LspT c IO ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> LspT c IO ()) -> IO () -> LspT c IO ()
forall a b. (a -> b) -> a -> b
$ Logger -> Text -> IO ()
logDebug (IdeState -> Logger
ideLogger IdeState
ideState) Text
"GhcIde.hover entered (ideLogger)" -- AZ
    IdeState
-> TextDocumentPositionParams
-> LspM c (Either ResponseError (Maybe Hover))
forall c.
IdeState
-> TextDocumentPositionParams
-> LspM c (Either ResponseError (Maybe Hover))
hover IdeState
ideState TextDocumentPositionParams :: TextDocumentIdentifier -> Position -> TextDocumentPositionParams
TextDocumentPositionParams{TextDocumentIdentifier
Position
$sel:_textDocument:TextDocumentPositionParams :: TextDocumentIdentifier
$sel:_position:TextDocumentPositionParams :: Position
_position :: Position
_textDocument :: TextDocumentIdentifier
..}

-- ---------------------------------------------------------------------
symbolsProvider :: IdeState -> PluginId -> DocumentSymbolParams -> LspM c (Either ResponseError (List DocumentSymbol |? List SymbolInformation))
symbolsProvider :: IdeState
-> PluginId
-> DocumentSymbolParams
-> LspM
     c
     (Either
        ResponseError (List DocumentSymbol |? List SymbolInformation))
symbolsProvider IdeState
ide PluginId
_ DocumentSymbolParams
params = IdeState
-> DocumentSymbolParams
-> LspM
     c
     (Either
        ResponseError (List DocumentSymbol |? List SymbolInformation))
forall c.
IdeState
-> DocumentSymbolParams
-> LspM
     c
     (Either
        ResponseError (List DocumentSymbol |? List SymbolInformation))
moduleOutline IdeState
ide DocumentSymbolParams
params

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