@@ -46,6 +46,8 @@ data HoogleError = NoDb | NoResults deriving (Eq,Ord,Show)
46
46
47
47
newtype HoogleDb = HoogleDb (Maybe FilePath )
48
48
49
+ -- | Convert Hoogle Error's to Ide Error's.
50
+ -- Can be used to present errors to the client.
49
51
hoogleErrorToIdeError :: HoogleError -> IdeError
50
52
hoogleErrorToIdeError NoResults =
51
53
IdeError PluginError " No results found" Null
@@ -55,6 +57,16 @@ hoogleErrorToIdeError NoDb =
55
57
instance ExtensionClass HoogleDb where
56
58
initialValue = HoogleDb Nothing
57
59
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.
68
+ -- However, it is still safe to use the hoogle API,
69
+ -- e.g. either error or default values are returned.
58
70
initializeHoogleDb :: IdeGhcM (Maybe FilePath )
59
71
initializeHoogleDb = do
60
72
explicitDbLocation <- liftIO $ lookupEnv " HIE_HOOGLE_DATABASE"
@@ -83,6 +95,15 @@ infoCmd' expr = do
83
95
else
84
96
return $ T. pack $ targetInfo $ head res
85
97
98
+ -- | Command to get the prettified documentation of an hoogle identifier.
99
+ -- Identifier should be understandable for hoogle.
100
+ -- If documentation can be found for it, the result will be rendered
101
+ -- in markdown for the lsp-client. If multiple results have been found,
102
+ -- only the first result will be shown.
103
+ --
104
+ -- If no result can be found for the identifier, a hoogle error is returned
105
+ -- that can be shown to the client by converting it
106
+ -- to an IdeError with 'hoogleErrorToIdeError'.
86
107
infoCmdFancyRender :: T. Text -> IdeM (Either HoogleError T. Text )
87
108
infoCmdFancyRender expr = do
88
109
HoogleDb mdb <- get
@@ -92,6 +113,8 @@ infoCmdFancyRender expr = do
92
113
else
93
114
return $ renderTarget $ head res
94
115
116
+ -- | Render the target in valid markdown.
117
+ -- Transform haddock documentation into markdown.
95
118
renderTarget :: Target -> T. Text
96
119
renderTarget t = T. intercalate " \n\n " $
97
120
[" ```haskell\n " <> unHTML (T. pack $ targetItem t) <> " ```" ]
@@ -114,12 +137,30 @@ renderTarget t = T.intercalate "\n\n" $
114
137
115
138
------------------------------------------------------------------------
116
139
140
+ -- | Search for modules that satisfy the given search text.
141
+ -- Will return at most five, unique results.
142
+ --
143
+ -- If an error occurs, such as no hoogle database has been found,
144
+ -- or the search term has no match, an empty list will be returned.
117
145
searchModules :: T. Text -> IdeM [T. Text ]
118
146
searchModules = fmap (nub . take 5 ) . searchTargets (fmap (T. pack . fst ) . targetModule)
119
147
148
+ -- | Search for packages that satisfy the given search text.
149
+ -- Will return at most five, unique results.
150
+ --
151
+ -- If an error occurs, such as no hoogle database has been found,
152
+ -- or the search term has no match, an empty list will be returned.
120
153
searchPackages :: T. Text -> IdeM [T. Text ]
121
154
searchPackages = fmap (nub . take 5 ) . searchTargets (fmap (T. pack . fst ) . targetPackage)
122
155
156
+ -- | Search for Targets that fit to the given Text and satisfy the given predicate.
157
+ -- Limits the amount of matches to at most ten.
158
+ -- Applies the predicate to the first ten matches. May also return zero matches,
159
+ -- although there are matches, if none of the first ten matches
160
+ -- satisfies the predicate.
161
+ --
162
+ -- If an error occurs, such as no hoogle database has been found,
163
+ -- or the search term has no match, an empty list will be returned.
123
164
searchTargets :: (Target -> Maybe a ) -> T. Text -> IdeM [a ]
124
165
searchTargets f term = do
125
166
HoogleDb mdb <- get
@@ -130,13 +171,19 @@ searchTargets f term = do
130
171
131
172
------------------------------------------------------------------------
132
173
174
+ -- | Lookup the given Text in the local Hoogle database.
175
+ -- Is limited to collect at most ten matches.
176
+ -- May fail with a HoogleError that can be shown to the user.
133
177
lookupCmd :: CommandFunc T. Text [T. Text ]
134
178
lookupCmd = CmdSync $ \ term -> do
135
179
res <- liftToGhc $ bimap hoogleErrorToIdeError id <$> lookupCmd' 10 term
136
180
return $ case res of
137
181
Left err -> IdeResultFail err
138
182
Right x -> IdeResultOk x
139
183
184
+ -- | Lookup the given Text in the local Hoogle database.
185
+ -- Takes the first `n` matches.
186
+ -- May fail with a HoogleError that can be shown to the user.
140
187
lookupCmd' :: Int -> T. Text -> IdeM (Either HoogleError [T. Text ])
141
188
lookupCmd' n term = do
142
189
HoogleDb mdb <- get
@@ -145,12 +192,36 @@ lookupCmd' n term = do
145
192
146
193
------------------------------------------------------------------------
147
194
195
+ -- | Run a query for Hoogle on the given Hoogle database.
196
+ -- If no Database is given, no search is executed.
197
+ -- If the Database cannot be found at the given location, an IOException will be thrown.
198
+ -- Note, that the database file must be an absolute path.
199
+ -- The target may be of the form: 'take', 'take :: Int -> [a] -> [a]', 'Data.List'.
200
+ -- In general, it is very similar to the Web Api.
201
+ -- Found targets can be consumed with the given callback function.
202
+ -- You can limit the amount of results, by taking only the first ten results.
203
+ -- Example call:
204
+ --
205
+ -- @
206
+ -- runHoogleQuery
207
+ -- (Just "/home/user/.hoogle/default-haskell-5.0.17.hoo")
208
+ -- (Data.Text.pack "take :: Int -> [a] -> [a]")
209
+ -- (Right . Prelude.take 10)
210
+ -- @
211
+ -- This limits the results to ten and looks for a function `take` that has the given signature.
212
+ --
213
+ -- HoogleError's can be translated to IdeErrors with @hoogleErrorToIdeError@
214
+ -- and shown to the client.
148
215
runHoogleQuery :: Maybe FilePath -> T. Text -> ([Target ] -> Either HoogleError a ) -> IO (Either HoogleError a )
149
216
runHoogleQuery Nothing _ _ = return $ Left NoDb
150
217
runHoogleQuery (Just db) quer f = do
151
218
res <- searchHoogle db quer
152
219
return (f res)
153
220
221
+
222
+ -- | Run a query for Hoogle on the given Hoogle database.
223
+ -- If the database can not be found, an IOException is thrown.
224
+ -- The target may be of the form: `take`, `take :: Int -> [a] -> [a]`
154
225
searchHoogle :: FilePath -> T. Text -> IO [Target ]
155
226
searchHoogle dbf quer = withDatabase dbf (return . flip searchDatabase (T. unpack quer))
156
227
@@ -167,7 +238,15 @@ docRules (Just "containers") modName =
167
238
fromMaybe modName $ T. stripSuffix " .Base" modName
168
239
docRules _ modName = modName
169
240
170
- getDocsForName :: T. Text -> Maybe T. Text -> T. Text -> IdeM (Maybe T. Text )
241
+ -- | Get the Documentation for a given identifier in a given module.
242
+ -- May also specify the according package, to avoid name clashes.
243
+ -- Results is a prettified Text that can be sent and shown to the client.
244
+ --
245
+ -- Might fail, if the identifier can not be found.
246
+ getDocsForName :: T. Text -- ^ Identifier within a module.
247
+ -> Maybe T. Text -- ^ Optional package name to avoid name clashes.
248
+ -> T. Text -- ^ Name of the module to search in.
249
+ -> IdeM (Maybe T. Text ) -- ^ Prettified hoogle documentation of target.
171
250
getDocsForName name pkg modName' = do
172
251
let modName = docRules pkg modName'
173
252
query = name
0 commit comments