这个 GSoC 项目的目标是提供一种便捷的方式在 Juno IDE 中访问文档。任何关于此项目的工作都必须在 Julia 方面(通过自省获取必要信息)*以及* 在 Atom 方面(展示这些信息)。
Julia 方面的大部分工作都投入到了一个新的包中,DocSeeker.jl,它实现了所有从已安装包中获取文档字符串所必需的自省功能;Atom.jl 中的一个小垫片 (Atom.jl#99) 然后将任何前端请求委托给该包。
前端工作直接包含在 Juno 堆栈中 (atom-julia-client#377 和 atom-ink#148,准确地说),因为它非常基础的 IDE 功能。
这里有两个主要挑战:*收集文档字符串* 和 *过滤文档字符串*,两者都以尽可能高效和可靠的方式进行。
DocSeeker.jl 包含一个函数 alldocs()
,它将返回有关当前 Julia 会话中所有可用符号的信息。这些符号可以通过递归遍历所有当前加载的 Module
并对它们调用 Base.names()
来轻松找到。此外,Julia 的文档系统会收集所有带有附加文档字符串的符号,这些符号可以轻松检索。
所有这些都非常慢——在我的机器上,加载了几个包后,大约需要半秒钟(并返回有关 ~13,000 个符号的信息)。同时,可用符号并不经常更改,因此缓存是一个可行的解决方案。
在过滤和搜索 alldocs
返回的符号(及其附加的文档字符串)时,有各种各样的选项需要考虑,但我选择了一些在测试过程中被证明是最重要的选项
导出:Julia 还没有(尚未)提供将某些符号作为模块公用 API 的一部分的方法,因此我使用导出符号的集合来代替。
模块:可以在指定的模块、所有加载的模块或所有已安装的模块中搜索。
搜索:仅在名称中搜索,或在名称和文档字符串中搜索。
最后一点需要更多信息,因为它不像前两点那样容易做到至少有点正确。这里的基本问题是(模糊的)全文搜索,这也是互联网深处每个搜索引擎所要做的。自然地,已经存在很多(开源)实现:solr、lunr(docs.julialang.org 使用的)、以及 SQL 的 FTS 扩展等等。
在夏季的早期阶段,我尝试了几件事来让它正常工作,但对当前问题来说,调用 Java 或 JavaScript 看起来有点过头,而 SQL.jl 给了我不少麻烦,而且默认情况下不提供 FTS 扩展。
自定义实现起初看起来并不难,但需要一个*好的* 评分函数,该函数给定一个搜索查询 needle
,将文档字符串映射到 0 到 1 之间的数字
起初我尝试编写自己的字符串比较函数(结果好坏参半),但后来我偶然发现了出色的 StringDistances.jl,它几乎满足了我的所有需求。
评分函数应用于线程循环中的所有相关符号(这在我的机器上可以免费获得 1.5 倍的加速);之后应用所有适用的过滤器,并返回前 20 个结果。
在我的机器上,过滤和搜索大约需要 0.1 秒,这意味着与检索文档字符串所需的时间相比,它几乎可以忽略不计。
现在 DocSeeker.jl 已经找到了我们要求的结果,是时候以一种吸引人的方式显示它们了:
如果你之前使用过 Juno,你可能会注意到改进的 Markdown 渲染(当然,它在整个 Juno 中都可用):有语法高亮、LaTeX 渲染和许多一般的改进。
除此之外,docpane UI 还显示了最相关的信息(绑定的类型、定义模块、绑定是否导出等);单击绑定将带你到定义位置,单击模块将提供有关该模块的一些信息。链接通常也工作正常(外部链接将在你的默认浏览器中打开,而使用 Documenter.jl 的 [link](@ref)
语法定义的链接将开始新的搜索)。
这些功能将在 2017 年 9 月初集成到 Juno 中,所以请随时尝试它们!
我要感谢 Mike Innes 在实现和功能方面的所有富有成效的讨论,以及他对 Julia/Juno 开发的指导(早在 GSoC 开始之前)。