@@ -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,14 @@ 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 not hoogle database has been found, Nothing is returned
67
+ -- and we will have no access to the hoogle database.
58
68
initializeHoogleDb :: IdeGhcM (Maybe FilePath )
59
69
initializeHoogleDb = do
60
70
explicitDbLocation <- liftIO $ lookupEnv " HIE_HOOGLE_DATABASE"
@@ -83,6 +93,14 @@ infoCmd' expr = do
83
93
else
84
94
return $ T. pack $ targetInfo $ head res
85
95
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'.
86
104
infoCmdFancyRender :: T. Text -> IdeM (Either HoogleError T. Text )
87
105
infoCmdFancyRender expr = do
88
106
HoogleDb mdb <- get
@@ -92,6 +110,8 @@ infoCmdFancyRender expr = do
92
110
else
93
111
return $ renderTarget $ head res
94
112
113
+ -- | Render the target in valid markdown.
114
+ -- Transform haddock documentation into markdown.
95
115
renderTarget :: Target -> T. Text
96
116
renderTarget t = T. intercalate " \n\n " $
97
117
[" ```haskell\n " <> unHTML (T. pack $ targetItem t) <> " ```" ]
@@ -114,12 +134,26 @@ renderTarget t = T.intercalate "\n\n" $
114
134
115
135
------------------------------------------------------------------------
116
136
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.
117
141
searchModules :: T. Text -> IdeM [T. Text ]
118
142
searchModules = fmap (nub . take 5 ) . searchTargets (fmap (T. pack . fst ) . targetModule)
119
143
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.
120
148
searchPackages :: T. Text -> IdeM [T. Text ]
121
149
searchPackages = fmap (nub . take 5 ) . searchTargets (fmap (T. pack . fst ) . targetPackage)
122
150
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.
123
157
searchTargets :: (Target -> Maybe a ) -> T. Text -> IdeM [a ]
124
158
searchTargets f term = do
125
159
HoogleDb mdb <- get
@@ -130,13 +164,19 @@ searchTargets f term = do
130
164
131
165
------------------------------------------------------------------------
132
166
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.
133
170
lookupCmd :: CommandFunc T. Text [T. Text ]
134
171
lookupCmd = CmdSync $ \ term -> do
135
172
res <- liftToGhc $ bimap hoogleErrorToIdeError id <$> lookupCmd' 10 term
136
173
return $ case res of
137
174
Left err -> IdeResultFail err
138
175
Right x -> IdeResultOk x
139
176
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.
140
180
lookupCmd' :: Int -> T. Text -> IdeM (Either HoogleError [T. Text ])
141
181
lookupCmd' n term = do
142
182
HoogleDb mdb <- get
@@ -145,12 +185,36 @@ lookupCmd' n term = do
145
185
146
186
------------------------------------------------------------------------
147
187
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.
148
208
runHoogleQuery :: Maybe FilePath -> T. Text -> ([Target ] -> Either HoogleError a ) -> IO (Either HoogleError a )
149
209
runHoogleQuery Nothing _ _ = return $ Left NoDb
150
210
runHoogleQuery (Just db) quer f = do
151
211
res <- searchHoogle db quer
152
212
return (f res)
153
213
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]`
154
218
searchHoogle :: FilePath -> T. Text -> IO [Target ]
155
219
searchHoogle dbf quer = withDatabase dbf (return . flip searchDatabase (T. unpack quer))
156
220
@@ -167,7 +231,15 @@ docRules (Just "containers") modName =
167
231
fromMaybe modName $ T. stripSuffix " .Base" modName
168
232
docRules _ modName = modName
169
233
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.
171
243
getDocsForName name pkg modName' = do
172
244
let modName = docRules pkg modName'
173
245
query = name
0 commit comments