Skip to content
This repository was archived by the owner on Oct 7, 2020. It is now read-only.

Commit 8f15fe1

Browse files
committed
Document Hoogle Plugin
1 parent e1b3157 commit 8f15fe1

File tree

1 file changed

+72
-1
lines changed

1 file changed

+72
-1
lines changed

src/Haskell/Ide/Engine/Plugin/Hoogle.hs

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ data HoogleError = NoDb | NoResults deriving (Eq,Ord,Show)
4646

4747
newtype HoogleDb = HoogleDb (Maybe FilePath)
4848

49+
-- | Convert Hoogle Error's to Ide Error's.
50+
-- Can be used to present errors to the client.
4951
hoogleErrorToIdeError :: HoogleError -> IdeError
5052
hoogleErrorToIdeError NoResults =
5153
IdeError PluginError "No results found" Null
@@ -55,6 +57,14 @@ hoogleErrorToIdeError NoDb =
5557
instance ExtensionClass HoogleDb where
5658
initialValue = HoogleDb Nothing
5759

60+
-- | Initialise the Hoogle Database.
61+
-- Search for the Hoogle Database and set it in the global config if found.
62+
-- Looks first into custom hoogle database locations, then in the default location.
63+
-- Note, that the FilePath must be an absolute path, otherwise Hoogle can not
64+
-- find the database.
65+
--
66+
-- If not hoogle database has been found, Nothing is returned
67+
-- and we will have no access to the hoogle database.
5868
initializeHoogleDb :: IdeGhcM (Maybe FilePath)
5969
initializeHoogleDb = do
6070
explicitDbLocation <- liftIO $ lookupEnv "HIE_HOOGLE_DATABASE"
@@ -83,6 +93,13 @@ infoCmd' expr = do
8393
else
8494
return $ T.pack $ targetInfo $ head res
8595

96+
-- | Command to get the prettified documentation of an hoogle identifier.
97+
-- Identifier should be understandable for hoogle.
98+
-- If documentation can be found for it, the result will be rendered
99+
-- in markdown for the lsp-client.
100+
--
101+
-- If no result can be found for the identifier, a hoogle error is returned
102+
-- that can be shown to the client.
86103
infoCmdFancyRender :: T.Text -> IdeM (Either HoogleError T.Text)
87104
infoCmdFancyRender expr = do
88105
HoogleDb mdb <- get
@@ -92,6 +109,8 @@ infoCmdFancyRender expr = do
92109
else
93110
return $ renderTarget $ head res
94111

112+
-- | Render the target in valid markdown.
113+
-- Transform haddock documentation into markdown.
95114
renderTarget :: Target -> T.Text
96115
renderTarget t = T.intercalate "\n\n" $
97116
["```haskell\n" <> unHTML (T.pack $ targetItem t) <> "```"]
@@ -114,12 +133,26 @@ renderTarget t = T.intercalate "\n\n" $
114133

115134
------------------------------------------------------------------------
116135

136+
-- | Search for modules that satisfy the given search text.
137+
-- Will return at most five, unique results.
138+
--
139+
-- If an error happens, such as no hoogle database found, an empty list will be returned.
117140
searchModules :: T.Text -> IdeM [T.Text]
118141
searchModules = fmap (nub . take 5) . searchTargets (fmap (T.pack . fst) . targetModule)
119142

143+
-- | Search for packages that satisfy the given search text.
144+
-- Will return at most five, unique results.
145+
--
146+
-- If an error happens, such as no hoogle database found, an empty list will be returned.
120147
searchPackages :: T.Text -> IdeM [T.Text]
121148
searchPackages = fmap (nub . take 5) . searchTargets (fmap (T.pack . fst) . targetPackage)
122149

150+
-- | Search for Targets that fit to the given Text and satisfy the given predicate.
151+
-- Limits the amount of matches to at most ten. Applies the predicate to the first ten matches.
152+
-- May also return zero matches, although there are matches, if none of the first ten matches
153+
-- satisfies the predicate.
154+
--
155+
-- If an error happens, such as no hoogle database found, an empty list will be returned.
123156
searchTargets :: (Target -> Maybe a) -> T.Text -> IdeM [a]
124157
searchTargets f term = do
125158
HoogleDb mdb <- get
@@ -130,13 +163,19 @@ searchTargets f term = do
130163

131164
------------------------------------------------------------------------
132165

166+
-- | Lookup the given Text in the local Hoogle database.
167+
-- Is limited to collect at most ten matches.
168+
-- May fail with a HoogleError that can be shown to the user.
133169
lookupCmd :: CommandFunc T.Text [T.Text]
134170
lookupCmd = CmdSync $ \term -> do
135171
res <- liftToGhc $ bimap hoogleErrorToIdeError id <$> lookupCmd' 10 term
136172
return $ case res of
137173
Left err -> IdeResultFail err
138174
Right x -> IdeResultOk x
139175

176+
-- | Lookup the given Text in the local Hoogle database.
177+
-- Takes the first `n` matches.
178+
-- May fail with a HoogleError that can be shown to the user.
140179
lookupCmd' :: Int -> T.Text -> IdeM (Either HoogleError [T.Text])
141180
lookupCmd' n term = do
142181
HoogleDb mdb <- get
@@ -145,12 +184,36 @@ lookupCmd' n term = do
145184

146185
------------------------------------------------------------------------
147186

187+
-- | Run a query for Hoogle on the given Hoogle database.
188+
-- If no Database is given, no search is executed.
189+
-- If the Database cannot be found at the given location, an IOException will be thrown.
190+
-- Note, that the database file must be an absolute path.
191+
-- The target may be of the form: 'take', 'take :: Int -> [a] -> [a]', 'Data.List'.
192+
-- In general, it is very similar to the Web Api.
193+
-- Found targets can be consumed with the given callback function.
194+
-- You can limit the amount of results, by taking only the first ten results.
195+
-- Example call:
196+
--
197+
-- @
198+
-- runHoogleQuery
199+
-- (Just "/home/user/.hoogle/default-haskell-5.0.17.hoo")
200+
-- (Data.Text.pack "take :: Int -> [a] -> [a]")
201+
-- (Right . Prelude.take 10)
202+
-- @
203+
-- This limits the results to ten and looks for a function `take` that has the given signature.
204+
--
205+
-- HoogleError's can be translated to IdeErrors with @hoogleErrorToIdeError@
206+
-- and shown to the client.
148207
runHoogleQuery :: Maybe FilePath -> T.Text -> ([Target] -> Either HoogleError a) -> IO (Either HoogleError a)
149208
runHoogleQuery Nothing _ _ = return $ Left NoDb
150209
runHoogleQuery (Just db) quer f = do
151210
res <- searchHoogle db quer
152211
return (f res)
153212

213+
214+
-- | Run a query for Hoogle on the given Hoogle database.
215+
-- If the database can not be found, an IOException is thrown.
216+
-- The target may be of the form: `take`, `take :: Int -> [a] -> [a]`
154217
searchHoogle :: FilePath -> T.Text -> IO [Target]
155218
searchHoogle dbf quer = withDatabase dbf (return . flip searchDatabase (T.unpack quer))
156219

@@ -167,7 +230,15 @@ docRules (Just "containers") modName =
167230
fromMaybe modName $ T.stripSuffix ".Base" modName
168231
docRules _ modName = modName
169232

170-
getDocsForName :: T.Text -> Maybe T.Text -> T.Text -> IdeM (Maybe T.Text)
233+
-- | Get the Documentation for a given identifier in a given module.
234+
-- May also specify the according package, to avoid name clashes.
235+
-- Results is a prettified Text that can be sent and shown to the client.
236+
--
237+
-- Might fail, if the identifier can not be found.
238+
getDocsForName :: T.Text -- ^ Identifier within a module.
239+
-> Maybe T.Text -- ^ Optional package name to avoid name clashes.
240+
-> T.Text -- ^ Name of the module to search in.
241+
-> IdeM (Maybe T.Text) -- ^ Prettified hoogle documentation of target.
171242
getDocsForName name pkg modName' = do
172243
let modName = docRules pkg modName'
173244
query = name

0 commit comments

Comments
 (0)