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

Commit 0e4a021

Browse files
committed
Document Hoogle Plugin
1 parent e1b3157 commit 0e4a021

File tree

1 file changed

+73
-1
lines changed

1 file changed

+73
-1
lines changed

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

Lines changed: 73 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,14 @@ 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 by converting it
103+
-- to an IdeError with 'hoogleErrorToIdeError'.
86104
infoCmdFancyRender :: T.Text -> IdeM (Either HoogleError T.Text)
87105
infoCmdFancyRender expr = do
88106
HoogleDb mdb <- get
@@ -92,6 +110,8 @@ infoCmdFancyRender expr = do
92110
else
93111
return $ renderTarget $ head res
94112

113+
-- | Render the target in valid markdown.
114+
-- Transform haddock documentation into markdown.
95115
renderTarget :: Target -> T.Text
96116
renderTarget t = T.intercalate "\n\n" $
97117
["```haskell\n" <> unHTML (T.pack $ targetItem t) <> "```"]
@@ -114,12 +134,26 @@ renderTarget t = T.intercalate "\n\n" $
114134

115135
------------------------------------------------------------------------
116136

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

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

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

131165
------------------------------------------------------------------------
132166

167+
-- | Lookup the given Text in the local Hoogle database.
168+
-- Is limited to collect at most ten matches.
169+
-- May fail with a HoogleError that can be shown to the user.
133170
lookupCmd :: CommandFunc T.Text [T.Text]
134171
lookupCmd = CmdSync $ \term -> do
135172
res <- liftToGhc $ bimap hoogleErrorToIdeError id <$> lookupCmd' 10 term
136173
return $ case res of
137174
Left err -> IdeResultFail err
138175
Right x -> IdeResultOk x
139176

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

146186
------------------------------------------------------------------------
147187

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

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

@@ -167,7 +231,15 @@ docRules (Just "containers") modName =
167231
fromMaybe modName $ T.stripSuffix ".Base" modName
168232
docRules _ modName = modName
169233

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

0 commit comments

Comments
 (0)