{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ViewPatterns #-}
module Ide.Plugin.ConfigUtils where
import Control.Lens (at, (&), (?~))
import qualified Data.Aeson as A
import Data.Aeson.Lens (_Object)
import qualified Data.Aeson.Types as A
import Data.Default
import qualified Data.Dependent.Map as DMap
import qualified Data.Dependent.Sum as DSum
import Data.List.Extra (nubOrd)
import Data.String (IsString (fromString))
import qualified Data.Text as T
import Ide.Plugin.Config
import Ide.Plugin.Properties (toDefaultJSON,
toVSCodeExtensionSchema)
import Ide.Types
import Language.LSP.Protocol.Message
pluginsToDefaultConfig :: IdePlugins a -> A.Value
pluginsToDefaultConfig :: forall a. IdePlugins a -> Value
pluginsToDefaultConfig IdePlugins {[PluginDescriptor a]
$sel:ipMap:IdePlugins :: forall ideState. IdePlugins ideState -> [PluginDescriptor ideState]
ipMap :: [PluginDescriptor a]
..} =
forall a. ToJSON a => a -> Value
A.toJSON Config
defaultConfig forall a b. a -> (a -> b) -> b
& forall t. AsValue t => Prism' t (KeyMap Value)
_Object forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall m. At m => Index m -> Lens' m (Maybe (IxValue m))
at Key
"plugin" forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ Value
elems
where
defaultConfig :: Config
defaultConfig@Config {} = forall a. Default a => a
def
elems :: Value
elems = [Pair] -> Value
A.object forall a b. (a -> b) -> a -> b
$ forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$ forall {a} {ideState}.
KeyValue a =>
PluginDescriptor ideState -> [a]
singlePlugin forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [PluginDescriptor a]
ipMap
singlePlugin :: PluginDescriptor ideState -> [a]
singlePlugin PluginDescriptor {$sel:pluginConfigDescriptor:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> ConfigDescriptor
pluginConfigDescriptor = ConfigDescriptor {Bool
CustomConfig
PluginConfig
$sel:configCustomConfig:ConfigDescriptor :: ConfigDescriptor -> CustomConfig
$sel:configHasDiagnostics:ConfigDescriptor :: ConfigDescriptor -> Bool
$sel:configInitialGenericConfig:ConfigDescriptor :: ConfigDescriptor -> PluginConfig
configCustomConfig :: CustomConfig
configHasDiagnostics :: Bool
configInitialGenericConfig :: PluginConfig
..}, Natural
[Text]
[PluginCommand ideState]
Maybe (ParserInfo (IdeCommand ideState))
Rules ()
PluginId
PluginNotificationHandlers ideState
PluginHandlers ideState
DynFlagsModifications
$sel:pluginFileType:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> [Text]
$sel:pluginCli:PluginDescriptor :: forall ideState.
PluginDescriptor ideState
-> Maybe (ParserInfo (IdeCommand ideState))
$sel:pluginModifyDynflags:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> DynFlagsModifications
$sel:pluginNotificationHandlers:PluginDescriptor :: forall ideState.
PluginDescriptor ideState -> PluginNotificationHandlers ideState
$sel:pluginHandlers:PluginDescriptor :: forall ideState.
PluginDescriptor ideState -> PluginHandlers ideState
$sel:pluginCommands:PluginDescriptor :: forall ideState.
PluginDescriptor ideState -> [PluginCommand ideState]
$sel:pluginRules:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> Rules ()
$sel:pluginPriority:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> Natural
$sel:pluginId:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> PluginId
pluginFileType :: [Text]
pluginCli :: Maybe (ParserInfo (IdeCommand ideState))
pluginModifyDynflags :: DynFlagsModifications
pluginNotificationHandlers :: PluginNotificationHandlers ideState
pluginHandlers :: PluginHandlers ideState
pluginCommands :: [PluginCommand ideState]
pluginRules :: Rules ()
pluginPriority :: Natural
pluginId :: PluginId
..} =
let x :: [Pair]
x = [Pair]
genericDefaultConfig forall a. Semigroup a => a -> a -> a
<> [Pair]
dedicatedDefaultConfig
in [forall a. IsString a => String -> a
fromString (Text -> String
T.unpack Text
pId) forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= [Pair] -> Value
A.object [Pair]
x | Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Pair]
x]
where
(PluginHandlers (forall {k1} (k2 :: k1 -> *) (f :: k1 -> *).
DMap k2 f -> [DSum k2 f]
DMap.toList -> [DSum IdeMethod (PluginHandler ideState)]
handlers)) = PluginHandlers ideState
pluginHandlers
customConfigToDedicatedDefaultConfig :: CustomConfig -> [Pair]
customConfigToDedicatedDefaultConfig (CustomConfig Properties r
p) = forall (r :: [PropertyKey]). Properties r -> [Pair]
toDefaultJSON Properties r
p
genericDefaultConfig :: [Pair]
genericDefaultConfig =
let x :: [Pair]
x = [Key
"diagnosticsOn" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Bool
True | Bool
configHasDiagnostics]
forall a. Semigroup a => a -> a -> a
<> forall a. Ord a => [a] -> [a]
nubOrd (forall a. Monoid a => [a] -> a
mconcat
(forall (f :: Method 'ClientToServer 'Request -> *).
PluginConfig -> DSum IdeMethod f -> [Pair]
handlersToGenericDefaultConfig PluginConfig
configInitialGenericConfig forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [DSum IdeMethod (PluginHandler ideState)]
handlers))
in case [Pair]
x of
[Pair
_] -> [Key
"globalOn" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= PluginConfig -> Bool
plcGlobalOn PluginConfig
configInitialGenericConfig]
[Pair]
_ -> [Pair]
x
dedicatedDefaultConfig :: [Pair]
dedicatedDefaultConfig =
let x :: [Pair]
x = CustomConfig -> [Pair]
customConfigToDedicatedDefaultConfig CustomConfig
configCustomConfig
in [Key
"config" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= [Pair] -> Value
A.object [Pair]
x | Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Pair]
x]
(PluginId Text
pId) = PluginId
pluginId
handlersToGenericDefaultConfig :: PluginConfig -> DSum.DSum IdeMethod f -> [A.Pair]
handlersToGenericDefaultConfig :: forall (f :: Method 'ClientToServer 'Request -> *).
PluginConfig -> DSum IdeMethod f -> [Pair]
handlersToGenericDefaultConfig PluginConfig{Bool
KeyMap Value
$sel:plcConfig:PluginConfig :: PluginConfig -> KeyMap Value
$sel:plcFoldingRangeOn:PluginConfig :: PluginConfig -> Bool
$sel:plcSelectionRangeOn:PluginConfig :: PluginConfig -> Bool
$sel:plcRenameOn:PluginConfig :: PluginConfig -> Bool
$sel:plcCompletionOn:PluginConfig :: PluginConfig -> Bool
$sel:plcSymbolsOn:PluginConfig :: PluginConfig -> Bool
$sel:plcHoverOn:PluginConfig :: PluginConfig -> Bool
$sel:plcDiagnosticsOn:PluginConfig :: PluginConfig -> Bool
$sel:plcCodeLensOn:PluginConfig :: PluginConfig -> Bool
$sel:plcCodeActionsOn:PluginConfig :: PluginConfig -> Bool
$sel:plcCallHierarchyOn:PluginConfig :: PluginConfig -> Bool
plcConfig :: KeyMap Value
plcFoldingRangeOn :: Bool
plcSelectionRangeOn :: Bool
plcRenameOn :: Bool
plcCompletionOn :: Bool
plcSymbolsOn :: Bool
plcHoverOn :: Bool
plcDiagnosticsOn :: Bool
plcCodeLensOn :: Bool
plcCodeActionsOn :: Bool
plcCallHierarchyOn :: Bool
plcGlobalOn :: Bool
$sel:plcGlobalOn:PluginConfig :: PluginConfig -> Bool
..} (IdeMethod SMethod a
m DSum.:=> f a
_) = case SMethod a
m of
SMethod a
SMethod_TextDocumentCodeAction -> [Key
"codeActionsOn" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Bool
plcCodeActionsOn]
SMethod a
SMethod_TextDocumentCodeLens -> [Key
"codeLensOn" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Bool
plcCodeLensOn]
SMethod a
SMethod_TextDocumentRename -> [Key
"renameOn" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Bool
plcRenameOn]
SMethod a
SMethod_TextDocumentHover -> [Key
"hoverOn" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Bool
plcHoverOn]
SMethod a
SMethod_TextDocumentDocumentSymbol -> [Key
"symbolsOn" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Bool
plcSymbolsOn]
SMethod a
SMethod_TextDocumentCompletion -> [Key
"completionOn" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Bool
plcCompletionOn]
SMethod a
SMethod_TextDocumentPrepareCallHierarchy -> [Key
"callHierarchyOn" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Bool
plcCallHierarchyOn]
SMethod a
_ -> []
pluginsToVSCodeExtensionSchema :: IdePlugins a -> A.Value
pluginsToVSCodeExtensionSchema :: forall a. IdePlugins a -> Value
pluginsToVSCodeExtensionSchema IdePlugins {[PluginDescriptor a]
ipMap :: [PluginDescriptor a]
$sel:ipMap:IdePlugins :: forall ideState. IdePlugins ideState -> [PluginDescriptor ideState]
..} = [Pair] -> Value
A.object forall a b. (a -> b) -> a -> b
$ forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$ forall {ideState}. PluginDescriptor ideState -> [Pair]
singlePlugin forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [PluginDescriptor a]
ipMap
where
singlePlugin :: PluginDescriptor ideState -> [Pair]
singlePlugin PluginDescriptor {$sel:pluginConfigDescriptor:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> ConfigDescriptor
pluginConfigDescriptor = ConfigDescriptor {Bool
CustomConfig
PluginConfig
configCustomConfig :: CustomConfig
configHasDiagnostics :: Bool
configInitialGenericConfig :: PluginConfig
$sel:configCustomConfig:ConfigDescriptor :: ConfigDescriptor -> CustomConfig
$sel:configHasDiagnostics:ConfigDescriptor :: ConfigDescriptor -> Bool
$sel:configInitialGenericConfig:ConfigDescriptor :: ConfigDescriptor -> PluginConfig
..}, Natural
[Text]
[PluginCommand ideState]
Maybe (ParserInfo (IdeCommand ideState))
Rules ()
PluginId
PluginNotificationHandlers ideState
PluginHandlers ideState
DynFlagsModifications
pluginFileType :: [Text]
pluginCli :: Maybe (ParserInfo (IdeCommand ideState))
pluginModifyDynflags :: DynFlagsModifications
pluginNotificationHandlers :: PluginNotificationHandlers ideState
pluginHandlers :: PluginHandlers ideState
pluginCommands :: [PluginCommand ideState]
pluginRules :: Rules ()
pluginPriority :: Natural
pluginId :: PluginId
$sel:pluginFileType:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> [Text]
$sel:pluginCli:PluginDescriptor :: forall ideState.
PluginDescriptor ideState
-> Maybe (ParserInfo (IdeCommand ideState))
$sel:pluginModifyDynflags:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> DynFlagsModifications
$sel:pluginNotificationHandlers:PluginDescriptor :: forall ideState.
PluginDescriptor ideState -> PluginNotificationHandlers ideState
$sel:pluginHandlers:PluginDescriptor :: forall ideState.
PluginDescriptor ideState -> PluginHandlers ideState
$sel:pluginCommands:PluginDescriptor :: forall ideState.
PluginDescriptor ideState -> [PluginCommand ideState]
$sel:pluginRules:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> Rules ()
$sel:pluginPriority:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> Natural
$sel:pluginId:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> PluginId
..} = [Pair]
genericSchema forall a. Semigroup a => a -> a -> a
<> [Pair]
dedicatedSchema
where
(PluginHandlers (forall {k1} (k2 :: k1 -> *) (f :: k1 -> *).
DMap k2 f -> [DSum k2 f]
DMap.toList -> [DSum IdeMethod (PluginHandler ideState)]
handlers)) = PluginHandlers ideState
pluginHandlers
customConfigToDedicatedSchema :: CustomConfig -> [Pair]
customConfigToDedicatedSchema (CustomConfig Properties r
p) = forall (r :: [PropertyKey]). Text -> Properties r -> [Pair]
toVSCodeExtensionSchema (Text -> Text
withIdPrefix Text
"config.") Properties r
p
(PluginId Text
pId) = PluginId
pluginId
genericSchema :: [Pair]
genericSchema =
let x :: [Pair]
x =
[Text -> Key
toKey' Text
"diagnosticsOn" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Text -> Value
schemaEntry Text
"diagnostics" | Bool
configHasDiagnostics]
forall a. Semigroup a => a -> a -> a
<> forall a. Ord a => [a] -> [a]
nubOrd (forall a. Monoid a => [a] -> a
mconcat (DSum IdeMethod (PluginHandler ideState) -> [Pair]
handlersToGenericSchema forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [DSum IdeMethod (PluginHandler ideState)]
handlers))
in case [Pair]
x of
[Pair
_] -> [Text -> Key
toKey' Text
"globalOn" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Text -> Value
schemaEntry Text
"plugin"]
[Pair]
_ -> [Pair]
x
dedicatedSchema :: [Pair]
dedicatedSchema = CustomConfig -> [Pair]
customConfigToDedicatedSchema CustomConfig
configCustomConfig
handlersToGenericSchema :: DSum IdeMethod (PluginHandler ideState) -> [Pair]
handlersToGenericSchema (IdeMethod SMethod a
m DSum.:=> PluginHandler ideState a
_) = case SMethod a
m of
SMethod a
SMethod_TextDocumentCodeAction -> [Text -> Key
toKey' Text
"codeActionsOn" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Text -> Value
schemaEntry Text
"code actions"]
SMethod a
SMethod_TextDocumentCodeLens -> [Text -> Key
toKey' Text
"codeLensOn" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Text -> Value
schemaEntry Text
"code lenses"]
SMethod a
SMethod_TextDocumentRename -> [Text -> Key
toKey' Text
"renameOn" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Text -> Value
schemaEntry Text
"rename"]
SMethod a
SMethod_TextDocumentHover -> [Text -> Key
toKey' Text
"hoverOn" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Text -> Value
schemaEntry Text
"hover"]
SMethod a
SMethod_TextDocumentDocumentSymbol -> [Text -> Key
toKey' Text
"symbolsOn" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Text -> Value
schemaEntry Text
"symbols"]
SMethod a
SMethod_TextDocumentCompletion -> [Text -> Key
toKey' Text
"completionOn" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Text -> Value
schemaEntry Text
"completions"]
SMethod a
SMethod_TextDocumentPrepareCallHierarchy -> [Text -> Key
toKey' Text
"callHierarchyOn" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Text -> Value
schemaEntry Text
"call hierarchy"]
SMethod a
_ -> []
schemaEntry :: Text -> Value
schemaEntry Text
desc =
[Pair] -> Value
A.object
[ Key
"scope" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Text -> Value
A.String Text
"resource",
Key
"type" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Text -> Value
A.String Text
"boolean",
Key
"default" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Bool
True,
Key
"description" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Text -> Value
A.String (Text
"Enables " forall a. Semigroup a => a -> a -> a
<> Text
pId forall a. Semigroup a => a -> a -> a
<> Text
" " forall a. Semigroup a => a -> a -> a
<> Text
desc)
]
withIdPrefix :: Text -> Text
withIdPrefix Text
x = Text
"haskell.plugin." forall a. Semigroup a => a -> a -> a
<> Text
pId forall a. Semigroup a => a -> a -> a
<> Text
"." forall a. Semigroup a => a -> a -> a
<> Text
x
toKey' :: Text -> Key
toKey' = forall a. IsString a => String -> a
fromString forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
withIdPrefix