{-# 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

-- Attention:
-- 'diagnosticsOn' will never be added into the default config or the schema,
-- since diagnostics emit in arbitrary shake rules -- we don't know
-- whether a plugin is capable of producing diagnostics.

-- | Generates a default 'Config', but remains only effective items
pluginsToDefaultConfig :: IdePlugins a -> A.Value
pluginsToDefaultConfig :: forall a. IdePlugins a -> Value
pluginsToDefaultConfig IdePlugins {[PluginDescriptor a]
ipMap :: [PluginDescriptor a]
$sel:ipMap:IdePlugins :: forall ideState. IdePlugins ideState -> [PluginDescriptor ideState]
..} =
  -- Use '_Object' and 'at' to get at the "plugin" key
  -- and actually set it.
  Config -> Value
forall a. ToJSON a => a -> Value
A.toJSON Config
defaultConfig Value -> (Value -> Value) -> Value
forall a b. a -> (a -> b) -> b
& (KeyMap Value -> Identity (KeyMap Value))
-> Value -> Identity Value
forall t. AsValue t => Prism' t (KeyMap Value)
Prism' Value (KeyMap Value)
_Object ((KeyMap Value -> Identity (KeyMap Value))
 -> Value -> Identity Value)
-> ((Maybe (IxValue (KeyMap Value)) -> Identity (Maybe Value))
    -> KeyMap Value -> Identity (KeyMap Value))
-> (Maybe (IxValue (KeyMap 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 Key
Index (KeyMap Value)
"plugin" ((Maybe (IxValue (KeyMap 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 {e} {a} {ideState}.
KeyValue e a =>
PluginDescriptor ideState -> [a]
singlePlugin (PluginDescriptor a -> [Pair]) -> [PluginDescriptor a] -> [[Pair]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [PluginDescriptor a]
ipMap
    -- Splice genericDefaultConfig and dedicatedDefaultConfig
    -- Example:
    --
    -- {
    --  "plugin-id": {
    --    "globalOn": true,
    --    "codeActionsOn": true,
    --    "codeLensOn": true,
    --    "config": {
    --      "property1": "foo"
    --     }
    --   }
    -- }
    singlePlugin :: PluginDescriptor ideState -> [a]
singlePlugin PluginDescriptor {$sel:pluginConfigDescriptor:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> ConfigDescriptor
pluginConfigDescriptor = ConfigDescriptor {Bool
CustomConfig
PluginConfig
configInitialGenericConfig :: PluginConfig
configHasDiagnostics :: Bool
configCustomConfig :: CustomConfig
$sel:configInitialGenericConfig:ConfigDescriptor :: ConfigDescriptor -> PluginConfig
$sel:configHasDiagnostics:ConfigDescriptor :: ConfigDescriptor -> Bool
$sel:configCustomConfig:ConfigDescriptor :: ConfigDescriptor -> CustomConfig
..}, Natural
[Text]
[PluginCommand ideState]
Maybe (ParserInfo (IdeCommand ideState))
Text
Rules ()
PluginId
PluginNotificationHandlers ideState
PluginHandlers ideState
DynFlagsModifications
pluginId :: PluginId
pluginDescription :: Text
pluginPriority :: Natural
pluginRules :: Rules ()
pluginCommands :: [PluginCommand ideState]
pluginHandlers :: PluginHandlers ideState
pluginNotificationHandlers :: PluginNotificationHandlers ideState
pluginModifyDynflags :: DynFlagsModifications
pluginCli :: Maybe (ParserInfo (IdeCommand ideState))
pluginFileType :: [Text]
$sel:pluginId:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> PluginId
$sel:pluginDescription:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> Text
$sel:pluginPriority:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> Natural
$sel:pluginRules:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> Rules ()
$sel:pluginCommands:PluginDescriptor :: forall ideState.
PluginDescriptor ideState -> [PluginCommand ideState]
$sel:pluginHandlers:PluginDescriptor :: forall ideState.
PluginDescriptor ideState -> PluginHandlers ideState
$sel:pluginNotificationHandlers:PluginDescriptor :: forall ideState.
PluginDescriptor ideState -> PluginNotificationHandlers ideState
$sel:pluginModifyDynflags:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> DynFlagsModifications
$sel:pluginCli:PluginDescriptor :: forall ideState.
PluginDescriptor ideState
-> Maybe (ParserInfo (IdeCommand ideState))
$sel:pluginFileType:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> [Text]
..} =
      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 v. ToJSON v => Key -> v -> a
forall e kv v. (KeyValue e 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 a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Pair]
x]
      where
        (PluginHandlers (DMap IdeMethod (PluginHandler ideState)
-> [DSum IdeMethod (PluginHandler ideState)]
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) = Properties r -> [Pair]
forall (r :: [PropertyKey]). Properties r -> [Pair]
toDefaultJSON Properties r
p
        -- Example:
        --
        -- {
        --   "codeActionsOn": true,
        --   "codeLensOn": true
        -- }
        --
        genericDefaultConfig :: [Pair]
genericDefaultConfig =
            let x :: [Pair]
x = [Key
"diagnosticsOn" Key -> Bool -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e 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. Ord a => [a] -> [a]
nubOrd ([[Pair]] -> [Pair]
forall a. Monoid a => [a] -> a
mconcat
                            (PluginConfig -> DSum IdeMethod (PluginHandler ideState) -> [Pair]
forall (f :: Method 'ClientToServer 'Request -> *).
PluginConfig -> DSum IdeMethod f -> [Pair]
handlersToGenericDefaultConfig PluginConfig
configInitialGenericConfig (DSum IdeMethod (PluginHandler ideState) -> [Pair])
-> [DSum IdeMethod (PluginHandler ideState)] -> [[Pair]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [DSum IdeMethod (PluginHandler ideState)]
handlers))
            in case [Pair]
x of
                    -- if the plugin has only one capability, we produce globalOn instead of the specific one;
                    -- otherwise we don't produce globalOn at all
                    [Pair
_] -> [Key
"globalOn" Key -> Bool -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
A..= PluginConfig -> Bool
plcGlobalOn PluginConfig
configInitialGenericConfig]
                    [Pair]
_   -> [Pair]
x
        -- Example:
        --
        -- {
        --  "config": {
        --      "property1": "foo"
        --   }
        --}
        dedicatedDefaultConfig :: [Pair]
dedicatedDefaultConfig =
          let x :: [Pair]
x = CustomConfig -> [Pair]
customConfigToDedicatedDefaultConfig CustomConfig
configCustomConfig
           in [Key
"config" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e 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 a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Pair]
x]

        (PluginId Text
pId) = PluginId
pluginId

        -- This function captures ide methods registered by the plugin, and then converts it to kv pairs
        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:plcGlobalOn:PluginConfig :: PluginConfig -> Bool
plcGlobalOn :: Bool
plcCallHierarchyOn :: Bool
plcCodeActionsOn :: Bool
plcCodeLensOn :: Bool
plcDiagnosticsOn :: Bool
plcHoverOn :: Bool
plcSymbolsOn :: Bool
plcCompletionOn :: Bool
plcRenameOn :: Bool
plcSelectionRangeOn :: Bool
plcFoldingRangeOn :: Bool
plcSemanticTokensOn :: Bool
plcConfig :: KeyMap Value
$sel:plcCallHierarchyOn:PluginConfig :: PluginConfig -> Bool
$sel:plcCodeActionsOn:PluginConfig :: PluginConfig -> Bool
$sel:plcCodeLensOn:PluginConfig :: PluginConfig -> Bool
$sel:plcDiagnosticsOn:PluginConfig :: PluginConfig -> Bool
$sel:plcHoverOn:PluginConfig :: PluginConfig -> Bool
$sel:plcSymbolsOn:PluginConfig :: PluginConfig -> Bool
$sel:plcCompletionOn:PluginConfig :: PluginConfig -> Bool
$sel:plcRenameOn:PluginConfig :: PluginConfig -> Bool
$sel:plcSelectionRangeOn:PluginConfig :: PluginConfig -> Bool
$sel:plcFoldingRangeOn:PluginConfig :: PluginConfig -> Bool
$sel:plcSemanticTokensOn:PluginConfig :: PluginConfig -> Bool
$sel:plcConfig:PluginConfig :: PluginConfig -> KeyMap Value
..} (IdeMethod SMethod a
m DSum.:=> f a
_) = case SMethod a
m of
          SMethod a
SMethod_TextDocumentCodeAction           -> [Key
"codeActionsOn" Key -> Bool -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
A..= Bool
plcCodeActionsOn]
          SMethod a
SMethod_TextDocumentCodeLens             -> [Key
"codeLensOn" Key -> Bool -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
A..= Bool
plcCodeLensOn]
          SMethod a
SMethod_TextDocumentRename               -> [Key
"renameOn" Key -> Bool -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
A..= Bool
plcRenameOn]
          SMethod a
SMethod_TextDocumentHover                -> [Key
"hoverOn" Key -> Bool -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
A..= Bool
plcHoverOn]
          SMethod a
SMethod_TextDocumentDocumentSymbol       -> [Key
"symbolsOn" Key -> Bool -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
A..= Bool
plcSymbolsOn]
          SMethod a
SMethod_TextDocumentCompletion           -> [Key
"completionOn" Key -> Bool -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
A..= Bool
plcCompletionOn]
          SMethod a
SMethod_TextDocumentPrepareCallHierarchy -> [Key
"callHierarchyOn" Key -> Bool -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
A..= Bool
plcCallHierarchyOn]
          SMethod a
SMethod_TextDocumentSemanticTokensFull   -> [Key
"semanticTokensOn" Key -> Bool -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
A..= Bool
plcSemanticTokensOn]
          SMethod a
SMethod_TextDocumentSemanticTokensFullDelta -> [Key
"semanticTokensOn" Key -> Bool -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
A..= Bool
plcSemanticTokensOn]
          SMethod a
_                                 -> []

-- | Generates json schema used in haskell vscode extension
-- Similar to 'pluginsToDefaultConfig' but simpler, since schema has a flatten structure
pluginsToVSCodeExtensionSchema :: IdePlugins a -> A.Value
pluginsToVSCodeExtensionSchema :: forall a. IdePlugins a -> Value
pluginsToVSCodeExtensionSchema IdePlugins {[PluginDescriptor a]
$sel:ipMap:IdePlugins :: forall ideState. IdePlugins ideState -> [PluginDescriptor ideState]
ipMap :: [PluginDescriptor a]
..} = [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 {ideState}. PluginDescriptor ideState -> [Pair]
singlePlugin (PluginDescriptor a -> [Pair]) -> [PluginDescriptor a] -> [[Pair]]
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
$sel:configInitialGenericConfig:ConfigDescriptor :: ConfigDescriptor -> PluginConfig
$sel:configHasDiagnostics:ConfigDescriptor :: ConfigDescriptor -> Bool
$sel:configCustomConfig:ConfigDescriptor :: ConfigDescriptor -> CustomConfig
configInitialGenericConfig :: PluginConfig
configHasDiagnostics :: Bool
configCustomConfig :: CustomConfig
..}, Natural
[Text]
[PluginCommand ideState]
Maybe (ParserInfo (IdeCommand ideState))
Text
Rules ()
PluginId
PluginNotificationHandlers ideState
PluginHandlers ideState
DynFlagsModifications
$sel:pluginId:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> PluginId
$sel:pluginDescription:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> Text
$sel:pluginPriority:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> Natural
$sel:pluginRules:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> Rules ()
$sel:pluginCommands:PluginDescriptor :: forall ideState.
PluginDescriptor ideState -> [PluginCommand ideState]
$sel:pluginHandlers:PluginDescriptor :: forall ideState.
PluginDescriptor ideState -> PluginHandlers ideState
$sel:pluginNotificationHandlers:PluginDescriptor :: forall ideState.
PluginDescriptor ideState -> PluginNotificationHandlers ideState
$sel:pluginModifyDynflags:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> DynFlagsModifications
$sel:pluginCli:PluginDescriptor :: forall ideState.
PluginDescriptor ideState
-> Maybe (ParserInfo (IdeCommand ideState))
$sel:pluginFileType:PluginDescriptor :: forall ideState. PluginDescriptor ideState -> [Text]
pluginId :: PluginId
pluginDescription :: Text
pluginPriority :: Natural
pluginRules :: Rules ()
pluginCommands :: [PluginCommand ideState]
pluginHandlers :: PluginHandlers ideState
pluginNotificationHandlers :: PluginNotificationHandlers ideState
pluginModifyDynflags :: DynFlagsModifications
pluginCli :: Maybe (ParserInfo (IdeCommand ideState))
pluginFileType :: [Text]
..} = [Pair]
genericSchema [Pair] -> [Pair] -> [Pair]
forall a. Semigroup a => a -> a -> a
<> [Pair]
dedicatedSchema
      where
        (PluginHandlers (DMap IdeMethod (PluginHandler ideState)
-> [DSum IdeMethod (PluginHandler ideState)]
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) = 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 v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
A..= Text -> Bool -> Value
schemaEntry Text
"diagnostics" Bool
True | Bool
configHasDiagnostics]
                  [Pair] -> [Pair] -> [Pair]
forall a. Semigroup a => a -> a -> a
<> [Pair] -> [Pair]
forall a. Ord a => [a] -> [a]
nubOrd ([[Pair]] -> [Pair]
forall a. Monoid a => [a] -> a
mconcat (PluginConfig -> DSum IdeMethod (PluginHandler ideState) -> [Pair]
handlersToGenericSchema PluginConfig
configInitialGenericConfig (DSum IdeMethod (PluginHandler ideState) -> [Pair])
-> [DSum IdeMethod (PluginHandler ideState)] -> [[Pair]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [DSum IdeMethod (PluginHandler ideState)]
handlers))
           in case [Pair]
x of
                -- If the plugin has only one capability, we produce globalOn instead of the specific one;
                -- otherwise we don't produce globalOn at all
                [Pair
_] -> [Text -> Key
toKey' Text
"globalOn" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
A..= Text -> Bool -> Value
schemaEntry Text
"plugin" (PluginConfig -> Bool
plcGlobalOn PluginConfig
configInitialGenericConfig)]
                [Pair]
_   -> [Pair]
x
        dedicatedSchema :: [Pair]
dedicatedSchema = CustomConfig -> [Pair]
customConfigToDedicatedSchema CustomConfig
configCustomConfig
        handlersToGenericSchema :: PluginConfig -> DSum IdeMethod (PluginHandler ideState) -> [Pair]
handlersToGenericSchema PluginConfig{Bool
KeyMap Value
$sel:plcGlobalOn:PluginConfig :: PluginConfig -> Bool
$sel:plcCallHierarchyOn:PluginConfig :: PluginConfig -> Bool
$sel:plcCodeActionsOn:PluginConfig :: PluginConfig -> Bool
$sel:plcCodeLensOn:PluginConfig :: PluginConfig -> Bool
$sel:plcDiagnosticsOn:PluginConfig :: PluginConfig -> Bool
$sel:plcHoverOn:PluginConfig :: PluginConfig -> Bool
$sel:plcSymbolsOn:PluginConfig :: PluginConfig -> Bool
$sel:plcCompletionOn:PluginConfig :: PluginConfig -> Bool
$sel:plcRenameOn:PluginConfig :: PluginConfig -> Bool
$sel:plcSelectionRangeOn:PluginConfig :: PluginConfig -> Bool
$sel:plcFoldingRangeOn:PluginConfig :: PluginConfig -> Bool
$sel:plcSemanticTokensOn:PluginConfig :: PluginConfig -> Bool
$sel:plcConfig:PluginConfig :: PluginConfig -> KeyMap Value
plcGlobalOn :: Bool
plcCallHierarchyOn :: Bool
plcCodeActionsOn :: Bool
plcCodeLensOn :: Bool
plcDiagnosticsOn :: Bool
plcHoverOn :: Bool
plcSymbolsOn :: Bool
plcCompletionOn :: Bool
plcRenameOn :: Bool
plcSelectionRangeOn :: Bool
plcFoldingRangeOn :: Bool
plcSemanticTokensOn :: Bool
plcConfig :: KeyMap Value
..} (IdeMethod SMethod a
m DSum.:=> PluginHandler ideState a
_) = case SMethod a
m of
          SMethod a
SMethod_TextDocumentCodeAction           -> [Text -> Key
toKey' Text
"codeActionsOn" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
A..= Text -> Bool -> Value
schemaEntry Text
"code actions" Bool
plcCodeActionsOn]
          SMethod a
SMethod_TextDocumentCodeLens             -> [Text -> Key
toKey' Text
"codeLensOn" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
A..= Text -> Bool -> Value
schemaEntry Text
"code lenses" Bool
plcCodeLensOn]
          SMethod a
SMethod_TextDocumentRename               -> [Text -> Key
toKey' Text
"renameOn" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
A..= Text -> Bool -> Value
schemaEntry Text
"rename" Bool
plcRenameOn]
          SMethod a
SMethod_TextDocumentHover                -> [Text -> Key
toKey' Text
"hoverOn" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
A..= Text -> Bool -> Value
schemaEntry Text
"hover" Bool
plcHoverOn]
          SMethod a
SMethod_TextDocumentDocumentSymbol       -> [Text -> Key
toKey' Text
"symbolsOn" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
A..= Text -> Bool -> Value
schemaEntry Text
"symbols" Bool
plcSymbolsOn]
          SMethod a
SMethod_TextDocumentCompletion           -> [Text -> Key
toKey' Text
"completionOn" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
A..= Text -> Bool -> Value
schemaEntry Text
"completions" Bool
plcCompletionOn]
          SMethod a
SMethod_TextDocumentPrepareCallHierarchy -> [Text -> Key
toKey' Text
"callHierarchyOn" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
A..= Text -> Bool -> Value
schemaEntry Text
"call hierarchy" Bool
plcCallHierarchyOn]
          SMethod a
SMethod_TextDocumentSemanticTokensFull   -> [Text -> Key
toKey' Text
"semanticTokensOn" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
A..= Text -> Bool -> Value
schemaEntry Text
"semantic tokens" Bool
plcSemanticTokensOn]
          SMethod a
SMethod_TextDocumentSemanticTokensFullDelta   -> [Text -> Key
toKey' Text
"semanticTokensOn" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
A..= Text -> Bool -> Value
schemaEntry Text
"semantic tokens" Bool
plcSemanticTokensOn]
          SMethod a
_                                        -> []
        schemaEntry :: Text -> Bool -> Value
schemaEntry Text
desc Bool
defaultVal =
          [Pair] -> Value
A.object
            [ Key
"scope" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
A..= Text -> Value
A.String Text
"resource",
              Key
"type" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
A..= Text -> Value
A.String Text
"boolean",
              Key
"default" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
A..= Bool -> Value
A.Bool Bool
defaultVal,
              Key
"description" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e 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