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

Commit 8aeafb9

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

File tree

1 file changed

+78
-1
lines changed

1 file changed

+78
-1
lines changed

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

Lines changed: 78 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 no 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,15 @@ 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. If multiple results have been found,
100+
-- only the first result will be shown.
101+
--
102+
-- If no result can be found for the identifier, a hoogle error is returned
103+
-- that can be shown to the client by converting it
104+
-- to an IdeError with 'hoogleErrorToIdeError'.
86105
infoCmdFancyRender :: T.Text -> IdeM (Either HoogleError T.Text)
87106
infoCmdFancyRender expr = do
88107
HoogleDb mdb <- get
@@ -92,6 +111,8 @@ infoCmdFancyRender expr = do
92111
else
93112
return $ renderTarget $ head res
94113

114+
-- | Render the target in valid markdown.
115+
-- Transform haddock documentation into markdown.
95116
renderTarget :: Target -> T.Text
96117
renderTarget t = T.intercalate "\n\n" $
97118
["```haskell\n" <> unHTML (T.pack $ targetItem t) <> "```"]
@@ -114,12 +135,30 @@ renderTarget t = T.intercalate "\n\n" $
114135

115136
------------------------------------------------------------------------
116137

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

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

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

131170
------------------------------------------------------------------------
132171

172+
-- | Lookup the given Text in the local Hoogle database.
173+
-- Is limited to collect at most ten matches.
174+
-- May fail with a HoogleError that can be shown to the user.
133175
lookupCmd :: CommandFunc T.Text [T.Text]
134176
lookupCmd = CmdSync $ \term -> do
135177
res <- liftToGhc $ bimap hoogleErrorToIdeError id <$> lookupCmd' 10 term
136178
return $ case res of
137179
Left err -> IdeResultFail err
138180
Right x -> IdeResultOk x
139181

182+
-- | Lookup the given Text in the local Hoogle database.
183+
-- Takes the first `n` matches.
184+
-- May fail with a HoogleError that can be shown to the user.
140185
lookupCmd' :: Int -> T.Text -> IdeM (Either HoogleError [T.Text])
141186
lookupCmd' n term = do
142187
HoogleDb mdb <- get
@@ -145,12 +190,36 @@ lookupCmd' n term = do
145190

146191
------------------------------------------------------------------------
147192

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

219+
220+
-- | Run a query for Hoogle on the given Hoogle database.
221+
-- If the database can not be found, an IOException is thrown.
222+
-- The target may be of the form: `take`, `take :: Int -> [a] -> [a]`
154223
searchHoogle :: FilePath -> T.Text -> IO [Target]
155224
searchHoogle dbf quer = withDatabase dbf (return . flip searchDatabase (T.unpack quer))
156225

@@ -167,7 +236,15 @@ docRules (Just "containers") modName =
167236
fromMaybe modName $ T.stripSuffix ".Base" modName
168237
docRules _ modName = modName
169238

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

0 commit comments

Comments
 (0)