diff --git a/src/docs.jl b/src/docs.jl index 88160273..6cf2d5d1 100644 --- a/src/docs.jl +++ b/src/docs.jl @@ -2,11 +2,42 @@ using DocSeeker import Markdown handle("searchdocs") do data - @destruct [mod || Main, nameOnly || false, exportedOnly || false, allPackages || false, query] = data - items = @errs DocSeeker.searchdocs(query, mod = mod, exportedonly = exportedOnly, - loaded = !allPackages, name_only = nameOnly) + @destruct [ + needle = query, + mod || "Main", + name_only = nameOnly || false, + exportedonly = exportedOnly || false, + allPackages || false + ] = data + searchdocs′( + needle; + # kwargs to be passed to `DocSeeker.searchdocs`: + # TODO: configuration for `maxreturns` + loaded = !allPackages, mod = getmodule(mod), exportedonly = exportedonly, name_only = name_only + ) +end + +function searchdocs′(needle; kwargs...) + items = _searchdocs(needle; kwargs...) + return processdocs(items) +end + +function _searchdocs(needle; kwargs...) + identifiers = split(needle, '.') + head = string(identifiers[1]) + mod = get(kwargs, :mod, Main) + if head ≠ needle && (nextmod = getfield′(mod, head)) isa Module + # if `head` is a module, update `needle` and `mod` + nextneedle = join(identifiers[2:end], '.') + nextkwargs = Dict(k => (k === :mod ? nextmod : v) for (k, v) in kwargs) + return _searchdocs(nextneedle; nextkwargs...) + end + + return @errs searchdocs(needle; kwargs...) +end - if items isa EvalError +function processdocs(items) + return if items isa EvalError errstr = sprint(showerror, items.err) err = startswith(errstr, "Please regenerate the") ? """ @@ -45,12 +76,16 @@ end handle("moduleinfo") do data @destruct [mod] = data + moduleinfo(mod) +end + +function moduleinfo(mod) d, items = getmoduleinfo(mod) items = [renderitem(i) for i in items] Dict(:doc => view(d), :items => items) end -getmoduleinfo(mod) = ispackage(mod) ? packageinfo(mod) : moduleinfo(mod) +getmoduleinfo(mod) = ispackage(mod) ? packageinfo(mod) : modinfo(mod) ispackage(mod) = Base.find_package(mod) ≠ nothing function packageinfo(mod) @@ -64,14 +99,21 @@ function packageinfo(mod) ), modulesymbols(mod) end -function moduleinfo(mod) - header = if mod ∈ ("Core", "Base", "Main") || first(split(mod, '.')) == "Base" - "## Standard module `$(mod)`" +function modinfo(mod) + header = "## " + header *= if mod in ("Core", "Base", "Main") + "Toplevel module:" + elseif first(split(mod, '.')) == "Core" + "Core sub module:" + elseif first(split(mod, '.')) == "Base" + "Base sub module:" else - "## Module `$mod`" - end * "\n---\n## Defined symbols:" |> renderMD + "Module:" + end + header *= " `$(mod)`" + header *= "\n---\n## Defined symbols:" - header, modulesymbols(mod) + return renderMD(header), modulesymbols(mod) end function modulesymbols(mod) @@ -82,7 +124,8 @@ end using Logging: with_logger using .Progress: JunoProgressLogger -handle("regeneratedocs") do +handle(() -> regeneratedocs(), "regeneratedocs") +function regeneratedocs() with_logger(JunoProgressLogger()) do @errs DocSeeker.createdocsdb() end diff --git a/test/docs.jl b/test/docs.jl new file mode 100644 index 00000000..88afe7ee --- /dev/null +++ b/test/docs.jl @@ -0,0 +1,24 @@ +@testset "docs" begin + @testset "searchdocs" begin + using Atom: searchdocs′, _searchdocs + + @test !searchdocs′("sin")[:error] + # module awareness + @test all(_searchdocs("getfield′"; mod = "Atom")) do (score, docobj) + docobj.mod == "Atom" + end + # strip module accessor + @test all(_searchdocs("Atom.getfield′"; mod = "Main")) do (score, docobj) + docobj.mod == "Atom" + end + end + + @testset "moduleinfo" begin + using Atom: moduleinfo + + @test_nowarn moduleinfo("Main") + @test all(moduleinfo("Atom")[:items]) do item + item[:mod] == "Atom" + end + end +end