{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ViewPatterns #-}
module Ide.Plugin.ConfigUtils where
import Control.Lens (at, ix, (&), (?~))
import qualified Data.Aeson as A
import Data.Aeson.Lens (_Object)
import qualified Data.Aeson.Types as A
import Data.Default (def)
import qualified Data.Dependent.Map as DMap
import qualified Data.Dependent.Sum as DSum
import Data.List (nub)
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.Types
pluginsToDefaultConfig :: IdePlugins a -> A.Value
pluginsToDefaultConfig :: IdePlugins a -> Value
pluginsToDefaultConfig IdePlugins {[(PluginId, PluginDescriptor a)]
ipMap :: forall ideState.
IdePlugins ideState -> [(PluginId, PluginDescriptor ideState)]
ipMap :: [(PluginId, PluginDescriptor a)]
..} =
Config -> Value
forall a. ToJSON a => a -> Value
A.toJSON Config
defaultConfig Value -> (Value -> Value) -> Value
forall a b. a -> (a -> b) -> b
& Index Value -> Traversal' Value (IxValue Value)
forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix Index Value
"haskell" ((Value -> Identity Value) -> Value -> Identity Value)
-> ((Maybe Value -> Identity (Maybe Value))
-> Value -> Identity Value)
-> (Maybe Value -> Identity (Maybe Value))
-> Value
-> Identity Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (KeyMap Value -> Identity (KeyMap Value))
-> Value -> Identity Value
forall t. AsValue t => Prism' t (KeyMap Value)
_Object ((KeyMap Value -> Identity (KeyMap Value))
-> Value -> Identity Value)
-> ((Maybe Value -> Identity (Maybe Value))
-> KeyMap Value -> Identity (KeyMap Value))
-> (Maybe Value -> Identity (Maybe Value))
-> Value
-> Identity Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index (KeyMap Value)
-> Lens' (KeyMap Value) (Maybe (IxValue (KeyMap Value)))
forall m. At m => Index m -> Lens' m (Maybe (IxValue m))
at Index (KeyMap Value)
"plugin" ((Maybe Value -> Identity (Maybe Value))
-> Value -> Identity Value)
-> Value -> Value -> Value
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ Value
elems
where
defaultConfig :: Config
defaultConfig@Config {} = Config
forall a. Default a => a
def
elems :: Value
elems = [Pair] -> Value
A.object ([Pair] -> Value) -> [Pair] -> Value
forall a b. (a -> b) -> a -> b
$ [[Pair]] -> [Pair]
forall a. Monoid a => [a] -> a
mconcat ([[Pair]] -> [Pair]) -> [[Pair]] -> [Pair]
forall a b. (a -> b) -> a -> b
$ PluginDescriptor a -> [Pair]
forall a a. KeyValue a => PluginDescriptor a -> [a]
singlePlugin (PluginDescriptor a -> [Pair]) -> [PluginDescriptor a] -> [[Pair]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((PluginId, PluginDescriptor a) -> PluginDescriptor a)
-> [(PluginId, PluginDescriptor a)] -> [PluginDescriptor a]
forall a b. (a -> b) -> [a] -> [b]
map (PluginId, PluginDescriptor a) -> PluginDescriptor a
forall a b. (a, b) -> b
snd [(PluginId, PluginDescriptor a)]
ipMap
singlePlugin :: PluginDescriptor a -> [a]
singlePlugin PluginDescriptor {pluginConfigDescriptor :: forall ideState. PluginDescriptor ideState -> ConfigDescriptor
pluginConfigDescriptor = ConfigDescriptor {Bool
CustomConfig
configCustomConfig :: ConfigDescriptor -> CustomConfig
configHasDiagnostics :: ConfigDescriptor -> Bool
configEnableGenericConfig :: ConfigDescriptor -> Bool
configCustomConfig :: CustomConfig
configHasDiagnostics :: Bool
configEnableGenericConfig :: Bool
..}, [PluginCommand a]
Maybe (ParserInfo (IdeCommand a))
Rules ()
PluginId
PluginNotificationHandlers a
PluginHandlers a
DynFlagsModifications
pluginCli :: forall ideState.
PluginDescriptor ideState
-> Maybe (ParserInfo (IdeCommand ideState))
pluginModifyDynflags :: forall ideState. PluginDescriptor ideState -> DynFlagsModifications
pluginNotificationHandlers :: forall ideState.
PluginDescriptor ideState -> PluginNotificationHandlers ideState
pluginHandlers :: forall ideState.
PluginDescriptor ideState -> PluginHandlers ideState
pluginCommands :: forall ideState.
PluginDescriptor ideState -> [PluginCommand ideState]
pluginRules :: forall ideState. PluginDescriptor ideState -> Rules ()
pluginId :: forall ideState. PluginDescriptor ideState -> PluginId
pluginCli :: Maybe (ParserInfo (IdeCommand a))
pluginModifyDynflags :: DynFlagsModifications
pluginNotificationHandlers :: PluginNotificationHandlers a
pluginHandlers :: PluginHandlers a
pluginCommands :: [PluginCommand a]
pluginRules :: Rules ()
pluginId :: PluginId
..} =
let x :: [Pair]
x = [Pair]
genericDefaultConfig [Pair] -> [Pair] -> [Pair]
forall a. Semigroup a => a -> a -> a
<> [Pair]
dedicatedDefaultConfig
in [String -> Key
forall a. IsString a => String -> a
fromString (Text -> String
T.unpack Text
pId) Key -> Value -> a
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= [Pair] -> Value
A.object [Pair]
x | Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [Pair] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Pair]
x]
where
(PluginHandlers (DMap IdeMethod (PluginHandler a)
-> [DSum IdeMethod (PluginHandler a)]
forall k1 (k2 :: k1 -> *) (f :: k1 -> *). DMap k2 f -> [DSum k2 f]
DMap.toList -> [DSum IdeMethod (PluginHandler a)]
handlers)) = PluginHandlers a
pluginHandlers
customConfigToDedicatedDefaultConfig :: CustomConfig -> [Pair]
customConfigToDedicatedDefaultConfig (CustomConfig Properties r
p) = Properties r -> [Pair]
forall (r :: [PropertyKey]). Properties r -> [Pair]
toDefaultJSON Properties r
p
genericDefaultConfig :: [Pair]
genericDefaultConfig =
let x :: [Pair]
x = [Key
"diagnosticsOn" Key -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Bool
True | Bool
configHasDiagnostics] [Pair] -> [Pair] -> [Pair]
forall a. Semigroup a => a -> a -> a
<> [Pair] -> [Pair]
forall a. Eq a => [a] -> [a]
nub ([[Pair]] -> [Pair]
forall a. Monoid a => [a] -> a
mconcat (DSum IdeMethod (PluginHandler a) -> [Pair]
forall (f :: Method 'FromClient 'Request -> *).
DSum IdeMethod f -> [Pair]
handlersToGenericDefaultConfig (DSum IdeMethod (PluginHandler a) -> [Pair])
-> [DSum IdeMethod (PluginHandler a)] -> [[Pair]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [DSum IdeMethod (PluginHandler a)]
handlers))
in case [Pair]
x of
[Pair
_] -> [Key
"globalOn" Key -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Bool
True]
[Pair]
_ -> [Pair]
x
dedicatedDefaultConfig :: [Pair]
dedicatedDefaultConfig =
let x :: [Pair]
x = CustomConfig -> [Pair]
customConfigToDedicatedDefaultConfig CustomConfig
configCustomConfig
in [Key
"config" Key -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= [Pair] -> Value
A.object [Pair]
x | Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [Pair] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Pair]
x]
(PluginId Text
pId) = PluginId
pluginId
handlersToGenericDefaultConfig :: DSum.DSum IdeMethod f -> [A.Pair]
handlersToGenericDefaultConfig :: DSum IdeMethod f -> [Pair]
handlersToGenericDefaultConfig (IdeMethod SMethod a
m DSum.:=> f a
_) = case SMethod a
m of
SMethod a
STextDocumentCodeAction -> [Key
"codeActionsOn" Key -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Bool
True]
SMethod a
STextDocumentCodeLens -> [Key
"codeLensOn" Key -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Bool
True]
SMethod a
STextDocumentRename -> [Key
"renameOn" Key -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Bool
True]
SMethod a
STextDocumentHover -> [Key
"hoverOn" Key -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Bool
True]
SMethod a
STextDocumentDocumentSymbol -> [Key
"symbolsOn" Key -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Bool
True]
SMethod a
STextDocumentCompletion -> [Key
"completionOn" Key -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Bool
True]
SMethod a
STextDocumentPrepareCallHierarchy -> [Key
"callHierarchyOn" Key -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Bool
True]
SMethod a
_ -> []
pluginsToVSCodeExtensionSchema :: IdePlugins a -> A.Value
pluginsToVSCodeExtensionSchema :: IdePlugins a -> Value
pluginsToVSCodeExtensionSchema IdePlugins {[(PluginId, PluginDescriptor a)]
ipMap :: [(PluginId, PluginDescriptor a)]
ipMap :: forall ideState.
IdePlugins ideState -> [(PluginId, PluginDescriptor ideState)]
..} = [Pair] -> Value
A.object ([Pair] -> Value) -> [Pair] -> Value
forall a b. (a -> b) -> a -> b
$ [[Pair]] -> [Pair]
forall a. Monoid a => [a] -> a
mconcat ([[Pair]] -> [Pair]) -> [[Pair]] -> [Pair]
forall a b. (a -> b) -> a -> b
$ PluginDescriptor a -> [Pair]
forall a. PluginDescriptor a -> [Pair]
singlePlugin (PluginDescriptor a -> [Pair]) -> [PluginDescriptor a] -> [[Pair]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((PluginId, PluginDescriptor a) -> PluginDescriptor a)
-> [(PluginId, PluginDescriptor a)] -> [PluginDescriptor a]
forall a b. (a -> b) -> [a] -> [b]
map (PluginId, PluginDescriptor a) -> PluginDescriptor a
forall a b. (a, b) -> b
snd [(PluginId, PluginDescriptor a)]
ipMap
where
singlePlugin :: PluginDescriptor a -> [Pair]
singlePlugin PluginDescriptor {pluginConfigDescriptor :: forall ideState. PluginDescriptor ideState -> ConfigDescriptor
pluginConfigDescriptor = ConfigDescriptor {Bool
CustomConfig
configCustomConfig :: CustomConfig
configHasDiagnostics :: Bool
configEnableGenericConfig :: Bool
configCustomConfig :: ConfigDescriptor -> CustomConfig
configHasDiagnostics :: ConfigDescriptor -> Bool
configEnableGenericConfig :: ConfigDescriptor -> Bool
..}, [PluginCommand a]
Maybe (ParserInfo (IdeCommand a))
Rules ()
PluginId
PluginNotificationHandlers a
PluginHandlers a
DynFlagsModifications
pluginCli :: Maybe (ParserInfo (IdeCommand a))
pluginModifyDynflags :: DynFlagsModifications
pluginNotificationHandlers :: PluginNotificationHandlers a
pluginHandlers :: PluginHandlers a
pluginCommands :: [PluginCommand a]
pluginRules :: Rules ()
pluginId :: PluginId
pluginCli :: forall ideState.
PluginDescriptor ideState
-> Maybe (ParserInfo (IdeCommand ideState))
pluginModifyDynflags :: forall ideState. PluginDescriptor ideState -> DynFlagsModifications
pluginNotificationHandlers :: forall ideState.
PluginDescriptor ideState -> PluginNotificationHandlers ideState
pluginHandlers :: forall ideState.
PluginDescriptor ideState -> PluginHandlers ideState
pluginCommands :: forall ideState.
PluginDescriptor ideState -> [PluginCommand ideState]
pluginRules :: forall ideState. PluginDescriptor ideState -> Rules ()
pluginId :: forall ideState. PluginDescriptor ideState -> PluginId
..} = [Pair]
genericSchema [Pair] -> [Pair] -> [Pair]
forall a. Semigroup a => a -> a -> a
<> [Pair]
dedicatedSchema
where
(PluginHandlers (DMap IdeMethod (PluginHandler a)
-> [DSum IdeMethod (PluginHandler a)]
forall k1 (k2 :: k1 -> *) (f :: k1 -> *). DMap k2 f -> [DSum k2 f]
DMap.toList -> [DSum IdeMethod (PluginHandler a)]
handlers)) = PluginHandlers a
pluginHandlers
customConfigToDedicatedSchema :: CustomConfig -> [Pair]
customConfigToDedicatedSchema (CustomConfig Properties r
p) = Text -> Properties r -> [Pair]
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" Key -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Text -> Value
schemaEntry Text
"diagnostics" | Bool
configHasDiagnostics]
[Pair] -> [Pair] -> [Pair]
forall a. Semigroup a => a -> a -> a
<> [Pair] -> [Pair]
forall a. Eq a => [a] -> [a]
nub ([[Pair]] -> [Pair]
forall a. Monoid a => [a] -> a
mconcat (DSum IdeMethod (PluginHandler a) -> [Pair]
handlersToGenericSchema (DSum IdeMethod (PluginHandler a) -> [Pair])
-> [DSum IdeMethod (PluginHandler a)] -> [[Pair]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [DSum IdeMethod (PluginHandler a)]
handlers))
in case [Pair]
x of
[Pair
_] -> [Text -> Key
toKey' Text
"globalOn" Key -> Value -> Pair
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 a) -> [Pair]
handlersToGenericSchema (IdeMethod m DSum.:=> PluginHandler a a
_) = case SMethod a
m of
SMethod a
STextDocumentCodeAction -> [Text -> Key
toKey' Text
"codeActionsOn" Key -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Text -> Value
schemaEntry Text
"code actions"]
SMethod a
STextDocumentCodeLens -> [Text -> Key
toKey' Text
"codeLensOn" Key -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Text -> Value
schemaEntry Text
"code lenses"]
SMethod a
STextDocumentRename -> [Text -> Key
toKey' Text
"renameOn" Key -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Text -> Value
schemaEntry Text
"rename"]
SMethod a
STextDocumentHover -> [Text -> Key
toKey' Text
"hoverOn" Key -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Text -> Value
schemaEntry Text
"hover"]
SMethod a
STextDocumentDocumentSymbol -> [Text -> Key
toKey' Text
"symbolsOn" Key -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Text -> Value
schemaEntry Text
"symbols"]
SMethod a
STextDocumentCompletion -> [Text -> Key
toKey' Text
"completionOn" Key -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Text -> Value
schemaEntry Text
"completions"]
SMethod a
STextDocumentPrepareCallHierarchy -> [Text -> Key
toKey' Text
"callHierarchyOn" Key -> Value -> Pair
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" Key -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Text -> Value
A.String Text
"resource",
Key
"type" Key -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Text -> Value
A.String Text
"boolean",
Key
"default" Key -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Bool
True,
Key
"description" Key -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
A..= Text -> Value
A.String (Text
"Enables " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
pId Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
desc)
]
withIdPrefix :: Text -> Text
withIdPrefix Text
x = Text
"haskell.plugin." Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
pId Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"." Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
x
toKey' :: Text -> Key
toKey' = String -> Key
forall a. IsString a => String -> a
fromString (String -> Key) -> (Text -> String) -> Text -> Key
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack (Text -> String) -> (Text -> Text) -> Text -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
withIdPrefix