@@ -1,12 +1,12 @@
1−module Idris.Apropos where
1+module Idris.Apropos (apropos, aproposModules) where
3import Idris.AbsSyntax
3import Idris.AbsSyntax
4import Idris.Core.Evaluate (ctxtAlist, Def(..))
4import Idris.Core.Evaluate (ctxtAlist, Def(..))
5import Idris.Core.TT (Name(..), Type, TT(..), NameType(..), Binder(..), Const(..),
5import Idris.Core.TT (Name(..), Type, TT(..), NameType(..), Binder(..), Const(..),
6 lookupCtxtExact, toAlist)
6 lookupCtxtExact, toAlist)
7−import Idris.Docstrings (Docstring, containsText)
7+import Idris.Docstrings (Docstring, DocTerm, containsText)
9−import Data.List (nub)
9+import Data.List (nub, nubBy, intersperse)
10import qualified Data.Text as T
10import qualified Data.Text as T
12-- | Find definitions that are relevant to all space-delimited components of
12-- | Find definitions that are relevant to all space-delimited components of
@@ -22,11 +22,25 @@ apropos ist what = let defs = ctxtAlist (tt_ctxt ist)
22 docs = toAlist (idris_docstrings ist)
22 docs = toAlist (idris_docstrings ist)
23 in nub (map fst (isAproposAll parts defs) ++
23 in nub (map fst (isAproposAll parts defs) ++
24 map fst (isAproposAll parts docs))
24 map fst (isAproposAll parts docs))
25− where isAproposAll [] xs = xs
25+ where isAproposAll [] xs = xs
26 isAproposAll (what:more) xs = filter (isApropos what)
26 isAproposAll (what:more) xs = filter (isApropos what)
27 (isAproposAll more xs)
27 (isAproposAll more xs)
28 parts = filter ((> 0) . T.length) . T.splitOn (T.pack " ") $ what
28 parts = filter ((> 0) . T.length) . T.splitOn (T.pack " ") $ what
30+-- | Find modules whose names or docstrings contain all the
31+-- space-delimited components of some string.
32+aproposModules :: IState -> T.Text -> [(String, Docstring DocTerm)]
33+aproposModules ist what = let mods = toAlist (idris_moduledocs ist)
34+ found = nubBy (\x y -> fst x == fst y)
35+ (isAproposAll parts mods)
36+ in map unModName found
37+ where isAproposAll [] xs = xs
38+ isAproposAll (what:more) xs = filter (\(n,d) -> isApropos what n || isApropos what d)
39+ (isAproposAll more xs)
40+ parts = filter ((> 0) . T.length) . T.splitOn (T.pack " ") $ what
41+ unModName (NS _ ns, d) = ((concat . intersperse "." . map T.unpack . reverse) ns, d)
42+ unModName (n, d) = ("<<MODULE>>", d)
30textIn :: T.Text -> T.Text -> Bool
44textIn :: T.Text -> T.Text -> Bool
31textIn a b = T.isInfixOf (T.toLower a) (T.toLower b)
45textIn a b = T.isInfixOf (T.toLower a) (T.toLower b)