Skip to content

Commit

Permalink
plugins' custom config params autogenerated docs — make it work
Browse files Browse the repository at this point in the history
  • Loading branch information
develop7 committed Oct 8, 2024
1 parent 7df3522 commit 182bad5
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 20 deletions.
56 changes: 37 additions & 19 deletions hls-plugin-api/src/Ide/Plugin/ConfigUtils.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ import qualified Data.Dependent.Sum as DSum
import Data.List.Extra (nubOrd)
import Data.String (IsString (fromString))
import qualified Data.Text as T
import GHC.TypeLits (symbolVal)
import Ide.Plugin.Config
import Ide.Plugin.Properties (Properties(..), toDefaultJSON,
toVSCodeExtensionSchema, SPropertyKey (SProperties), MetaData (..), SomePropertyKeyWithMetaData (..))
import Ide.Plugin.Properties (MetaData (..), Properties (..),
toDefaultJSON,
toVSCodeExtensionSchema)
import Ide.Types
import Language.LSP.Protocol.Message
import GHC.TypeLits (symbolVal)

-- Attention:
-- 'diagnosticsOn' will never be added into the default config or the schema,
Expand Down Expand Up @@ -141,24 +142,41 @@ pluginsToVSCodeExtensionSchema IdePlugins {..} = A.object $ mconcat $ singlePlug
withIdPrefix x = "haskell.plugin." <> pId <> "." <> x
toKey' = fromString . T.unpack . withIdPrefix

data PluginCustomConfig = PluginCustomConfig {
pccHeader :: T.Text,
pccParams :: [PluginCustomConfigParam]
}
data PluginCustomConfigParam = PluginCustomConfigParam {
pccpName :: T.Text,
pccpDescription :: T.Text,
pccpIsDefault :: Bool
}

-- | Generates markdown tables for custom config
pluginsCustomConfigToMarkdownTables :: IdePlugins a -> T.Text
pluginsCustomConfigToMarkdownTables IdePlugins {..} = T.unlines $ map singlePlugin ipMap
pluginsCustomConfigToMarkdownTables IdePlugins {..} = T.unlines
$ map renderCfg
$ filter (\(PluginCustomConfig _ params) -> not $ null params)
$ map pluginCfg ipMap
where
singlePlugin PluginDescriptor {pluginConfigDescriptor = ConfigDescriptor {configCustomConfig = c}, pluginId = PluginId pId} =
T.unlines (pluginHeader : tableHeader : rows c)
renderCfg :: PluginCustomConfig -> T.Text
renderCfg (PluginCustomConfig pId pccParams) =
T.unlines (pluginHeader : tableHeader : rows pccParams)
where
pluginHeader = "## " <> pId
tableHeader = "| Property | Description | Default |"
rows (CustomConfig p) = toMarkdownTable p
toMarkdownTable :: Properties r -> [T.Text]
toMarkdownTable EmptyProperties = mempty
toMarkdownTable (ConsProperties keyNameProxy k m xs) = renderRow (T.pack $ symbolVal keyNameProxy) (SomePropertyKeyWithMetaData k m) : toMarkdownTable xs
renderRow :: T.Text -> SomePropertyKeyWithMetaData -> T.Text
renderRow key (SomePropertyKeyWithMetaData k m) =
let (desc, defaultVal) = case m of
PropertiesMetaData _ desc _ -> (desc, False)
EnumMetaData _ desc _ _ -> ("", True)
MetaData _ desc -> (desc, False)
in T.unwords ["|", key, "|", desc, "|", if defaultVal then "yes" else "no", "|"]

tableHeader = "| Property | Description | Default |" <> "\n" <> "| --- | --- | --- |"
rows = map renderRow
renderRow (PluginCustomConfigParam name desc isDefault) =
"| `" <> name <> "` | " <> desc <> " | " <> if isDefault then "Yes" else "No" <> " |"
pluginCfg :: PluginDescriptor r -> PluginCustomConfig
pluginCfg PluginDescriptor {pluginConfigDescriptor = ConfigDescriptor {configCustomConfig = c}, pluginId = PluginId pId} =
PluginCustomConfig pId (pccProcess c)
where
pccProcess :: CustomConfig -> [PluginCustomConfigParam]
pccProcess (CustomConfig EmptyProperties) = mempty
pccProcess (CustomConfig (ConsProperties keyNameProxy _k m xs)) =
let (desc, isDefault) = case m of
PropertiesMetaData _ desc _ -> (desc, False)
EnumMetaData _ desc _ _ -> (desc, True)
MetaData _ desc -> (desc, False)
in PluginCustomConfigParam (T.pack $ symbolVal keyNameProxy) desc isDefault : pccProcess (CustomConfig xs)
4 changes: 4 additions & 0 deletions src/Ide/Arguments.hs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ getArguments exeName plugins = execParser opts
<|> hsubparser
( command "vscode-extension-schema" extensionSchemaCommand
<> command "generate-default-config" generateDefaultConfigCommand
<> command "plugins-custom-config-markdown-reference" pluginsCustomConfigMarkdownReferenceCommand
)
<|> listPluginsParser
<|> BiosMode <$> biosParser
Expand All @@ -87,6 +88,9 @@ getArguments exeName plugins = execParser opts
generateDefaultConfigCommand =
info (pure DefaultConfigurationMode)
(fullDesc <> progDesc "Print config supported by the server with default values")
pluginsCustomConfigMarkdownReferenceCommand =
info (pure PluginsCustomConfigMarkdownReferenceMode)
(fullDesc <> progDesc "Print markdown reference for plugins custom config")

printVersionParser :: String -> Parser PrintVersion
printVersionParser exeName =
Expand Down
6 changes: 5 additions & 1 deletion src/Ide/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import Data.Function ((&))
import Data.List (sortOn)
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.IO as T (putStrLn)
import Data.Text.Lazy.Encoding (decodeUtf8)
import qualified Data.Text.Lazy.IO as LT
import Development.IDE.Core.Rules hiding (Log)
Expand All @@ -28,7 +29,8 @@ import HIE.Bios.Types hiding (Log)
import qualified HIE.Bios.Types as HieBios
import Ide.Arguments
import Ide.Logger as G
import Ide.Plugin.ConfigUtils (pluginsToDefaultConfig,
import Ide.Plugin.ConfigUtils (pluginsCustomConfigToMarkdownTables,
pluginsToDefaultConfig,
pluginsToVSCodeExtensionSchema)
import Ide.Types (IdePlugins, PluginId (PluginId),
describePlugin, ipMap, pluginId)
Expand Down Expand Up @@ -103,6 +105,8 @@ defaultMain recorder args idePlugins = do

VSCodeExtensionSchemaMode -> do
LT.putStrLn $ decodeUtf8 $ encodePrettySorted $ pluginsToVSCodeExtensionSchema idePlugins
PluginsCustomConfigMarkdownReferenceMode -> do
T.putStrLn $ pluginsCustomConfigToMarkdownTables idePlugins
DefaultConfigurationMode -> do
LT.putStrLn $ decodeUtf8 $ encodePrettySorted $ pluginsToDefaultConfig idePlugins
PrintLibDir -> do
Expand Down
9 changes: 9 additions & 0 deletions test/functional/ConfigSchema.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ tests = testGroup "generate schema"
, goldenGitDiff "generate-default-config" (defaultConfigFp ghcVersion) $ do
stdout <- readProcess hlsExeCommand ["generate-default-config"] ""
pure $ BS.pack stdout
, goldenGitDiff "plugins-custom-config-markdown-reference" (markdownReferenceFp ghcVersion) $ do
stdout <- readProcess hlsExeCommand ["plugins-custom-config-markdown-reference"] ""
pure $ BS.pack stdout
]

vscodeSchemaFp :: GhcVersion -> FilePath
Expand All @@ -39,11 +42,17 @@ vscodeSchemaFp ghcVer = "test" </> "testdata" </> "schema" </> prettyGhcVersion
defaultConfigFp :: GhcVersion -> FilePath
defaultConfigFp ghcVer = "test" </> "testdata" </> "schema" </> prettyGhcVersion ghcVer </> generateDefaultConfigJson

markdownReferenceFp :: GhcVersion -> FilePath
markdownReferenceFp ghcVer = "test" </> "testdata" </> "schema" </> prettyGhcVersion ghcVer </> markdownReferenceMd

vscodeSchemaJson :: FilePath
vscodeSchemaJson = "vscode-extension-schema.golden.json"

generateDefaultConfigJson :: FilePath
generateDefaultConfigJson = "default-config.golden.json"

markdownReferenceMd :: FilePath
markdownReferenceMd = "markdown-reference.md"

prettyGhcVersion :: GhcVersion -> String
prettyGhcVersion ghcVer = map toLower (show ghcVer)
66 changes: 66 additions & 0 deletions test/testdata/schema/ghc96/markdown-reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
## ghcide-completions
| Property | Description | Default |
| --- | --- | --- |
| autoExtendOn | Extends the import list automatically when completing a out-of-scope identifier | No |
| snippetsOn | Inserts snippets when using code completions | No |

## semanticTokens
| Property | Description | Default |
| --- | --- | --- |
| variableToken | LSP semantic token type to use for variables | Yes
| functionToken | LSP semantic token type to use for functions | Yes
| dataConstructorToken | LSP semantic token type to use for data constructors | Yes
| typeVariableToken | LSP semantic token type to use for type variables | Yes
| classMethodToken | LSP semantic token type to use for typeclass methods | Yes
| patternSynonymToken | LSP semantic token type to use for pattern synonyms | Yes
| typeConstructorToken | LSP semantic token type to use for type constructors | Yes
| classToken | LSP semantic token type to use for typeclasses | Yes
| typeSynonymToken | LSP semantic token type to use for type synonyms | Yes
| typeFamilyToken | LSP semantic token type to use for type families | Yes
| recordFieldToken | LSP semantic token type to use for record fields | Yes
| operatorToken | LSP semantic token type to use for operators | Yes
| moduleToken | LSP semantic token type to use for modules | Yes

## fourmolu
| Property | Description | Default |
| --- | --- | --- |
| external | Call out to an external "fourmolu" executable, rather than using the bundled library. | No |
| path | Set path to executable (for "external" mode). | No |

## cabal-gild
| Property | Description | Default |
| --- | --- | --- |
| path | Set path to 'cabal-gild' executable | No |

## hlint
| Property | Description | Default |
| --- | --- | --- |
| flags | Flags used by hlint | No |

## ormolu
| Property | Description | Default |
| --- | --- | --- |
| external | Call out to an external "ormolu" executable, rather than using the bundled library | No |

## ghcide-type-lenses
| Property | Description | Default |
| --- | --- | --- |
| mode | Control how type lenses are shown | Yes

## cabal-fmt
| Property | Description | Default |
| --- | --- | --- |
| path | Set path to 'cabal-fmt' executable | No |

## eval
| Property | Description | Default |
| --- | --- | --- |
| exception | Enable marking exceptions with `*** Exception:` similarly to doctest and GHCi. | No |
| diff | Enable the diff output (WAS/NOW) of eval lenses | No |

## rename
| Property | Description | Default |
| --- | --- | --- |
| crossModule | Enable experimental cross-module renaming | No |


0 comments on commit 182bad5

Please sign in to comment.