@@ -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 no 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,15 @@ 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. 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'.
86
105
infoCmdFancyRender :: T. Text -> IdeM (Either HoogleError T. Text )
87
106
infoCmdFancyRender expr = do
88
107
HoogleDb mdb <- get
@@ -92,6 +111,8 @@ infoCmdFancyRender expr = do
92
111
else
93
112
return $ renderTarget $ head res
94
113
114
+ -- | Render the target in valid markdown.
115
+ -- Transform haddock documentation into markdown.
95
116
renderTarget :: Target -> T. Text
96
117
renderTarget t = T. intercalate " \n\n " $
97
118
[" ```haskell\n " <> unHTML (T. pack $ targetItem t) <> " ```" ]
@@ -114,12 +135,30 @@ renderTarget t = T.intercalate "\n\n" $
114
135
115
136
------------------------------------------------------------------------
116
137
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.
117
143
searchModules :: T. Text -> IdeM [T. Text ]
118
144
searchModules = fmap (nub . take 5 ) . searchTargets (fmap (T. pack . fst ) . targetModule)
119
145
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.
120
151
searchPackages :: T. Text -> IdeM [T. Text ]
121
152
searchPackages = fmap (nub . take 5 ) . searchTargets (fmap (T. pack . fst ) . targetPackage)
122
153
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.
123
162
searchTargets :: (Target -> Maybe a ) -> T. Text -> IdeM [a ]
124
163
searchTargets f term = do
125
164
HoogleDb mdb <- get
@@ -130,13 +169,19 @@ searchTargets f term = do
130
169
131
170
------------------------------------------------------------------------
132
171
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.
133
175
lookupCmd :: CommandFunc T. Text [T. Text ]
134
176
lookupCmd = CmdSync $ \ term -> do
135
177
res <- liftToGhc $ bimap hoogleErrorToIdeError id <$> lookupCmd' 10 term
136
178
return $ case res of
137
179
Left err -> IdeResultFail err
138
180
Right x -> IdeResultOk x
139
181
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.
140
185
lookupCmd' :: Int -> T. Text -> IdeM (Either HoogleError [T. Text ])
141
186
lookupCmd' n term = do
142
187
HoogleDb mdb <- get
@@ -145,12 +190,36 @@ lookupCmd' n term = do
145
190
146
191
------------------------------------------------------------------------
147
192
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.
148
213
runHoogleQuery :: Maybe FilePath -> T. Text -> ([Target ] -> Either HoogleError a ) -> IO (Either HoogleError a )
149
214
runHoogleQuery Nothing _ _ = return $ Left NoDb
150
215
runHoogleQuery (Just db) quer f = do
151
216
res <- searchHoogle db quer
152
217
return (f res)
153
218
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]`
154
223
searchHoogle :: FilePath -> T. Text -> IO [Target ]
155
224
searchHoogle dbf quer = withDatabase dbf (return . flip searchDatabase (T. unpack quer))
156
225
@@ -167,7 +236,15 @@ docRules (Just "containers") modName =
167
236
fromMaybe modName $ T. stripSuffix " .Base" modName
168
237
docRules _ modName = modName
169
238
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.
171
248
getDocsForName name pkg modName' = do
172
249
let modName = docRules pkg modName'
173
250
query = name
0 commit comments