Skip to content

Commit 369c229

Browse files
committed
feat: introduced plugins' custom config params autogenerated docs
Introduces plugins-custom-config-markdown-reference subcommand which extracts plugins' custom config parameters and renders a Markdown table with all the reference information.
1 parent b1966ff commit 369c229

File tree

9 files changed

+398
-4
lines changed

9 files changed

+398
-4
lines changed

hls-plugin-api/src/Ide/Plugin/ConfigUtils.hs

Lines changed: 99 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55

66
module Ide.Plugin.ConfigUtils (
77
pluginsToDefaultConfig,
8-
pluginsToVSCodeExtensionSchema
8+
pluginsToVSCodeExtensionSchema,
9+
pluginsCustomConfigToMarkdownTables
910
) where
1011

1112
import Control.Lens (at, (&), (?~))
@@ -18,8 +19,15 @@ import qualified Data.Dependent.Sum as DSum
1819
import Data.List.Extra (nubOrd)
1920
import Data.String (IsString (fromString))
2021
import qualified Data.Text as T
22+
import GHC.TypeLits (symbolVal)
2123
import Ide.Plugin.Config
22-
import Ide.Plugin.Properties (toDefaultJSON,
24+
import Ide.Plugin.Properties (KeyNameProxy, MetaData (..),
25+
PluginCustomConfig (..),
26+
PluginCustomConfigParam (..),
27+
Properties (..),
28+
SPropertyKey (..),
29+
SomePropertyKeyWithMetaData (..),
30+
toDefaultJSON,
2331
toVSCodeExtensionSchema)
2432
import Ide.Types
2533
import Language.LSP.Protocol.Message
@@ -143,3 +151,92 @@ pluginsToVSCodeExtensionSchema IdePlugins {..} = A.object $ mconcat $ singlePlug
143151
]
144152
withIdPrefix x = "haskell.plugin." <> pId <> "." <> x
145153
toKey' = fromString . T.unpack . withIdPrefix
154+
155+
156+
-- | Generates markdown tables for custom config
157+
pluginsCustomConfigToMarkdownTables :: IdePlugins a -> T.Text
158+
pluginsCustomConfigToMarkdownTables IdePlugins {..} = T.unlines
159+
$ map renderCfg
160+
$ filter (\(PluginCustomConfig _ params) -> not $ null params)
161+
$ map toPluginCustomConfig ipMap
162+
where
163+
toPluginCustomConfig :: PluginDescriptor ideState -> PluginCustomConfig
164+
toPluginCustomConfig PluginDescriptor {pluginConfigDescriptor = ConfigDescriptor {configCustomConfig = c}, pluginId = PluginId pId} =
165+
PluginCustomConfig { pcc'Name = pId, pcc'Params = toPluginCustomConfigParams c}
166+
toPluginCustomConfigParams :: CustomConfig -> [PluginCustomConfigParam]
167+
toPluginCustomConfigParams (CustomConfig p) = toPluginCustomConfigParams' p
168+
toPluginCustomConfigParams' :: Properties r -> [PluginCustomConfigParam]
169+
toPluginCustomConfigParams' EmptyProperties = []
170+
toPluginCustomConfigParams' (ConsProperties (keyNameProxy :: KeyNameProxy s) (k :: SPropertyKey k) (m :: MetaData t) xs) =
171+
toEntry (SomePropertyKeyWithMetaData k m) : toPluginCustomConfigParams' xs
172+
where
173+
toEntry :: SomePropertyKeyWithMetaData -> PluginCustomConfigParam
174+
toEntry (SomePropertyKeyWithMetaData SNumber MetaData {..}) =
175+
PluginCustomConfigParam {
176+
pccp'Name = T.pack $ symbolVal keyNameProxy,
177+
pccp'Description = description,
178+
pccp'Default = T.pack $ show defaultValue,
179+
pccp'EnumValues = []
180+
}
181+
toEntry (SomePropertyKeyWithMetaData SInteger MetaData {..}) =
182+
PluginCustomConfigParam {
183+
pccp'Name = T.pack $ symbolVal keyNameProxy,
184+
pccp'Description = description,
185+
pccp'Default = T.pack $ show defaultValue,
186+
pccp'EnumValues = []
187+
}
188+
toEntry (SomePropertyKeyWithMetaData SString MetaData {..}) =
189+
PluginCustomConfigParam {
190+
pccp'Name = T.pack $ symbolVal keyNameProxy,
191+
pccp'Description = description,
192+
pccp'Default = T.pack $ show defaultValue,
193+
pccp'EnumValues = []
194+
}
195+
toEntry (SomePropertyKeyWithMetaData SBoolean MetaData {..}) =
196+
PluginCustomConfigParam {
197+
pccp'Name = T.pack $ symbolVal keyNameProxy,
198+
pccp'Description = description,
199+
pccp'Default = T.pack $ show defaultValue,
200+
pccp'EnumValues = []
201+
}
202+
toEntry (SomePropertyKeyWithMetaData (SObject _) MetaData {..}) =
203+
PluginCustomConfigParam {
204+
pccp'Name = T.pack $ symbolVal keyNameProxy,
205+
pccp'Description = description,
206+
pccp'Default = "TODO: nested object", -- T.pack $ show defaultValue,
207+
pccp'EnumValues = []
208+
}
209+
toEntry (SomePropertyKeyWithMetaData (SArray _) MetaData {..}) =
210+
PluginCustomConfigParam {
211+
pccp'Name = T.pack $ symbolVal keyNameProxy,
212+
pccp'Description = description,
213+
pccp'Default = "TODO: Array values", -- T.pack $ show defaultValue,
214+
pccp'EnumValues = []
215+
}
216+
toEntry (SomePropertyKeyWithMetaData (SEnum _) EnumMetaData {..}) =
217+
PluginCustomConfigParam {
218+
pccp'Name = T.pack $ symbolVal keyNameProxy,
219+
pccp'Description = description,
220+
pccp'Default = T.pack $ show defaultValue,
221+
pccp'EnumValues = map (T.pack . show) enumValues
222+
}
223+
toEntry (SomePropertyKeyWithMetaData SProperties PropertiesMetaData {..}) =
224+
PluginCustomConfigParam {
225+
pccp'Name = T.pack $ symbolVal keyNameProxy,
226+
pccp'Description = description,
227+
pccp'Default = T.pack $ show defaultValue,
228+
pccp'EnumValues = []
229+
}
230+
renderCfg :: PluginCustomConfig -> T.Text
231+
renderCfg (PluginCustomConfig pId pccParams) =
232+
T.unlines (pluginHeader : tableHeader : rows pccParams)
233+
where
234+
pluginHeader = "## " <> pId
235+
tableHeader =
236+
"| Property | Description | Default | Allowed values |" <> "\n" <>
237+
"| --- | --- | --- | --- |"
238+
rows = map renderRow
239+
renderRow PluginCustomConfigParam {..} =
240+
"| `" <> pccp'Name <> "` | " <> pccp'Description <> " | `" <> pccp'Default <> "` | " <> renderEnum pccp'EnumValues <> " |"
241+
renderEnum [] = " &nbsp; " -- Placeholder to prevent missing cells
242+
renderEnum vs = "<ul> " <> (T.intercalate " " $ map (\x -> "<li><code>" <> x <> "</code></li>") vs) <> " </ul>"

hls-plugin-api/src/Ide/Plugin/Properties.hs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ module Ide.Plugin.Properties
2121
MetaData (..),
2222
PropertyKey (..),
2323
SPropertyKey (..),
24+
SomePropertyKeyWithMetaData (..),
2425
KeyNameProxy (..),
2526
KeyNamePath (..),
26-
Properties,
27+
Properties(..),
2728
HasProperty,
2829
HasPropertyByPath,
2930
emptyProperties,
@@ -42,6 +43,8 @@ module Ide.Plugin.Properties
4243
usePropertyByPathEither,
4344
usePropertyByPath,
4445
(&),
46+
PluginCustomConfig(..),
47+
PluginCustomConfigParam(..),
4548
)
4649
where
4750

@@ -516,3 +519,15 @@ toVSCodeExtensionSchema' ps = case ps of
516519
]
517520
(SomePropertyKeyWithMetaData SProperties PropertiesMetaData {..}) ->
518521
map (first Just) $ toVSCodeExtensionSchema' childrenProperties
522+
523+
data PluginCustomConfig = PluginCustomConfig {
524+
pcc'Name :: T.Text,
525+
pcc'Params :: [PluginCustomConfigParam]
526+
}
527+
data PluginCustomConfigParam = PluginCustomConfigParam {
528+
pccp'Name :: T.Text,
529+
pccp'Description :: T.Text,
530+
pccp'Default :: T.Text,
531+
pccp'EnumValues :: [T.Text]
532+
}
533+

src/Ide/Arguments.hs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ data Arguments
3333
| BiosMode BiosAction
3434
| Ghcide GhcideArguments
3535
| VSCodeExtensionSchemaMode
36+
| PluginsCustomConfigMarkdownReferenceMode
3637
| DefaultConfigurationMode
3738
| PrintLibDir
3839

@@ -69,6 +70,7 @@ getArguments exeName plugins = execParser opts
6970
<|> hsubparser
7071
( command "vscode-extension-schema" extensionSchemaCommand
7172
<> command "generate-default-config" generateDefaultConfigCommand
73+
<> command "plugins-custom-config-markdown-reference" pluginsCustomConfigMarkdownReferenceCommand
7274
)
7375
<|> listPluginsParser
7476
<|> BiosMode <$> biosParser
@@ -86,6 +88,9 @@ getArguments exeName plugins = execParser opts
8688
generateDefaultConfigCommand =
8789
info (pure DefaultConfigurationMode)
8890
(fullDesc <> progDesc "Print config supported by the server with default values")
91+
pluginsCustomConfigMarkdownReferenceCommand =
92+
info (pure PluginsCustomConfigMarkdownReferenceMode)
93+
(fullDesc <> progDesc "Print markdown reference for plugins custom config")
8994

9095
printVersionParser :: String -> Parser PrintVersion
9196
printVersionParser exeName =

src/Ide/Main.hs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import Data.Function ((&))
1515
import Data.List (sortOn)
1616
import Data.Text (Text)
1717
import qualified Data.Text as T
18+
import qualified Data.Text.IO as T (putStrLn)
1819
import Data.Text.Lazy.Encoding (decodeUtf8)
1920
import qualified Data.Text.Lazy.IO as LT
2021
import Development.IDE.Core.Rules hiding (Log)
@@ -28,7 +29,8 @@ import HIE.Bios.Types hiding (Log)
2829
import qualified HIE.Bios.Types as HieBios
2930
import Ide.Arguments
3031
import Ide.Logger as G
31-
import Ide.Plugin.ConfigUtils (pluginsToDefaultConfig,
32+
import Ide.Plugin.ConfigUtils (pluginsCustomConfigToMarkdownTables,
33+
pluginsToDefaultConfig,
3234
pluginsToVSCodeExtensionSchema)
3335
import Ide.Types (IdePlugins, PluginId (PluginId),
3436
describePlugin, ipMap, pluginId)
@@ -103,6 +105,8 @@ defaultMain recorder args idePlugins = do
103105

104106
VSCodeExtensionSchemaMode -> do
105107
LT.putStrLn $ decodeUtf8 $ encodePrettySorted $ pluginsToVSCodeExtensionSchema idePlugins
108+
PluginsCustomConfigMarkdownReferenceMode -> do
109+
T.putStrLn $ pluginsCustomConfigToMarkdownTables idePlugins
106110
DefaultConfigurationMode -> do
107111
LT.putStrLn $ decodeUtf8 $ encodePrettySorted $ pluginsToDefaultConfig idePlugins
108112
PrintLibDir -> do

test/functional/ConfigSchema.hs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ tests = testGroup "generate schema"
3131
, goldenGitDiff "generate-default-config" (defaultConfigFp ghcVersion) $ do
3232
stdout <- readProcess hlsExeCommand ["generate-default-config"] ""
3333
pure $ BS.pack stdout
34+
, goldenGitDiff "plugins-custom-config-markdown-reference" (markdownReferenceFp ghcVersion) $ do
35+
stdout <- readProcess hlsExeCommand ["plugins-custom-config-markdown-reference"] ""
36+
pure $ BS.pack stdout
3437
]
3538

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

45+
markdownReferenceFp :: GhcVersion -> FilePath
46+
markdownReferenceFp ghcVer = "test" </> "testdata" </> "schema" </> prettyGhcVersion ghcVer </> markdownReferenceMd
47+
4248
vscodeSchemaJson :: FilePath
4349
vscodeSchemaJson = "vscode-extension-schema.golden.json"
4450

4551
generateDefaultConfigJson :: FilePath
4652
generateDefaultConfigJson = "default-config.golden.json"
4753

54+
markdownReferenceMd :: FilePath
55+
markdownReferenceMd = "markdown-reference.md"
56+
4857
prettyGhcVersion :: GhcVersion -> String
4958
prettyGhcVersion ghcVer = map toLower (show ghcVer)

0 commit comments

Comments
 (0)