这是一封“情书”,写给那些给我的生活带来巨大改变的工具

新闻资讯   2023-06-07 14:04   77   0  


作者 | Hynek Schlawack
译者 | 平川
策划 | 刘燕
我是如何成为一名拥有“果蝇”记忆的高效程序员的。

本文最初发布于 Hynek Schlawack 的个人博客。

编程领域多年来的变化

我在 20 世纪 90 年代中期开始涉足 AmigaBASIC,与那时相比,编程变得更加多样化了。当时,关于你正在为之编程的计算机,你可以买一本大部头的书,99% 的内容里面都有。当你打开一个单色编辑器输入代码时,那本书总是放在旁边触手可及的地方,上面满是标记和便利贴。

现如今,一本单是介绍前端 Web 框架的书,都要比 C64 程序员编写一个完整的游戏所需的书还要厚。另一方面,我们编写代码所需的一切信息通常只需一次点击就可以获得。

没有人会为开发文档付费——不管是微软还是苹果都在 Web 上提供了所有人都可以免费使用的文档。开源项目就更不用说了!

在 npm、PyPI 和 GitHub 的时代,为什么还要操作系统以外的东西,要说清楚这个问题并不容易。那以前就是一个有争议的决定,必须审慎权衡。过去,我们通常都是将依赖项与产品一起交付。


有新的可选项是好事,多样化是好处的,但是,这会导致你提高生产力所需信息的碎片化。

对于正在使用的程序包,在同一时刻,人们要打开 10 几个页签来查看 API 文档。作为一个在世界最佳冲浪景点工作过的人,我可以告诉你,当没有网络时,在线文档就会成为一个问题,尤其是当你需要使用网站的搜索功能时。

如果你和我一样,通晓多种编程语言,面对大量的子社区(即使都是用 Python,但 Flask + SQLAlchemy + Postgres 与编写基于 asyncio 的网络服务器也存在着很大的差异),很难想象一个人可以记住他所使用的每个方法的参数。主要是,如果你真和我一样,会经常忘记自己的电话号码。

这就是我为什么说,2021 年发现 Dash 于我而言是一件改变人生的大事。

API 文档浏览器

大脑是为创造想法而生的,而不是为记住想法— David Allen


Dash 搜索

Dash 赋予了我一键获取所有相关 API 的能力:

  • 我按下“空格”键,就会弹出一个浮动窗口,上面有一个激活的搜索栏;

  • 我开始输入 API 或主题的大致名称;

  • 我选择一个输入建议项,跳转到正式项目文档的相应位置上;

  • 我按下 Escape,浮窗消失,编辑器再次获得焦点,我立马就可以开始输入了;

  • 我忘了刚才看了什么,就再次按下空格,浮动弹窗在同样的位置出现。

这个过程非常短暂——所有这些操作不到 2 秒即可完成,因此,这不会打断我的思维。我只是下意识地完成了那些操作。被遗忘的原生应用之乐——是的,我知道 https://devdocs.io。

所有 API 文档都可以一键获取,这对我们的帮助太大了。

我花在记忆函数参数或类导入路径上的精力越少,我投入思考解决问题的精力就越多。

我自认为不是那种特别聪明的人,所以我得借机降低自己的心理负荷。

虽然 Dash 的 Mac 版本售价为 30 美元,但在 Windows 和 Linux 上有一个免费的版本 Zeal。另外,Windows 上还有一个收费版本 Velocity。当然,也有一个 Emacs 程序包可以提供同样的功能:helm-dash。

也就是说,在任何平台上你都可以体验到这种 API 之乐。在本文接下来的部分中,我将只介绍 Dash,因为我在使用它,不过,除非特别注明,以下内容对上述各个版本均适用。

我不知道为什么,但像 Alfred 或 VS Code 这样的应用程序也有无数的插件。无论在哪里,我都喜欢使用同样的快捷键组合查找文档。这就是我对许多在线 API 浏览器不感兴趣的原因——我希望可以在 5 秒钟内切入切出文档。

它们有一个共同点,就是本地文档的格式是一样的。

文档集

它们都基于苹果的文档集 Bundles(docsets),其中包括 HTML 文档目录、保存在 XML 属性列表中的元数据以及保存在 SQLite 数据库中的搜索索引:

some.docset└── Contents    ├── Info.plist # ← 元数据    └── Resources        ├── Documents # ← HTML文档根路径        │   └── index.html        └── docSet.dsidx  # ← SQLite db w/ 搜索索引

如果你的磁盘上有一堆 HTML 文件,那么你可以将其转换成一个 docset ,提供给 Dash。那只是包含元数据的 HTML 文件。由于这些文件都在你自己的磁盘上,所以操作都是离线的。

因此,docsets 可以代替你保存在本地计算机上的文档,不用做任何特殊的处理,就可以实现更快的离线访问。只要将其打包成必要的目录结构,添加一个空索引,填写简单的元数据。

Shazam!现在,你可以一键让它们出现,一键让它们消失。

让我们回到无聊的历史课堂,从头开始看:我每天都要在无数的平台上使用无数的项目。我这里说的不只是编程 API,还包括:Ansible role、CSS class、HAProxy 配置、Postgres (和 SQL)特性……诸如此类,数不胜数。

安装好的 Dash docsets

虽然 Dash 自带了 Python 和 Go 核心文档, 而且 Godoc 文档可以通过 URL 直接添加,但无论 Dash 如何努力:在现代软件开发的碎片化世界里,它永远无法提供我需要的一切。

Sphinx

对我来说,其最大的缺失是(不仅仅)主导 Python 生态的 Sphinx 文档。

Sphinx 是一个语言无关的文档编写框架。不管是 API 文档,还是叙事性文档,都可以,而且提供丰富的链接。之前,它因为要求用户必须使用 reStructuredText 而声名狼藉,但现在,越来越多的项目使用 MyST 程序包来编写 Markdown 格式的文档。如果你对 Sphinx 文档的样式有任何先入为主的看法,我建议你浏览下 Sphinx Themes Gallery,看看 Sphinx 文档可以多漂亮。它是用 Python 编写的,但应用广泛,苹果的 Swift、LLVM(Clang!) 项目以及一些特别流行的 PHP 项目都在使用它。

而且,它恰好提供了缺失的部分:API 条目、章节、术语表、配置选项、命令行参数等的索引——所有这些都以你喜欢的方式分散在你的文档中,但总是可以相互链接。我觉得这很好,特别是如果你遵循一个系统性的框架,如 Diátaxis。

从技术上讲,让这项工作成为可能的关键组件只是一个扩展:ntersphinx。顾名思义,它最初用于项目间的链接,为我们提供一种机器可读的索引。后来,该索引变得如此流行,现在 MkDocs 扩展 mkdocstrings 和 pydoctor 也提供了支持。你可以通过那个索引文件(objects.inv)准确识别兼容 intersphinx 的文档。

这就是为什么,十年前的今天,我启动了 doc2dash 项目。

doc2dash

doc2dash 是一个命令行工具,你可以从 Homebrew tap 获取,也可以从发布页面下载 Linux、macOS 和 Windows 的预构建二进制文件,还可以从 PyPI 安装。

然后,你所要做的就是将其指向一个兼容 intersphinx 的文档目录,doc2dash 会帮你完成所需的一切工作,并生成一个 docset。

doc2dash 转换

请注意,这个工具的名字是 doc2dash 而非 sphinx2dash。我一直希望它能够成为一个编写高质量转换器的框架,最早的是 Sphinx 和 pydoctor。很遗憾,我的希望落空了——这也不难理解,每个社区都希望使用自己的语言和工具。

不过,在我看来,这些工具通常看起来都是一次性的,所以我想再次声明一下,我愿意与其他人一起增加对其他文档格式的支持。

不要重复发明轮子,框架已经有了!只是几行代码而已!你不必跟我和全世界分享你的解析器。事实是,Dash 和 doc2dash 都已存在超过 10 年之久,我仍然看到朋友们会打开无数个 API 文档页签,这让我非常难过。我不断向人们展示 Dash 的实际用途,他们总是说它很酷,并把它列入未来某一天的计划。除非再推一把,否则那一天总也不会到来。

本文的果蝇部分到此结束,接下来,我将试着用一个快速上手教程来推动你,让今天成为那未来的某一天!

教程:转换和提交文档

本教程旨在教你如何将兼容 intersphinx 的文档转换成 docset ,并提交到 Dash 的用户 docset 注册中心,这样,其他人就不用重复你的工作了。

假设你已经选择并安装了自己的 API 浏览器。你使用哪一个都没有关系,不过本教程使用 Dash。为了最后可以有选择的提交 docset ,你还需要对 GitHub 以及 pull 请求工作流有一个基本的了解。

我将以本教程为契机,开始发布自己项目的 docsets,首先从 structlog 开始。我建议你选择一个兼容 intersphinx 但 Dash 还不支持而你又经常访问其文档的项目。

让我们开始吧!

安装 doc2dash

如果你已经在使用 Homebrew,那么获取 doc2dash 最简单的方法是使用我的 GitHub 库 tap:

$ brew install hynek/tap/doc2dash

也有面向 Linux x86-64 和 macOS 的预构建二进制包,适用于 x86-64 和 Apple Silicon,因此,应该很快就可以安装完成。

除非你了解 Python 打包方法,否则第二好的方法是使用发布页面提供的预构建二进制文件。当前,上面提供了适用于 Linux、Windows 和 macOS 的二进制文件,全都是针对 x86-64。如果受欢迎的话,我将来会提供更多面向其他平台的构建。

最后,你可以从 PyPI 获取。我强烈建议使用 pipx,以下是使用它运行 doc2dash 最简单的方法:

$ pipx run doc2dash --help
高级技巧:如果你了解 PyPy ,知道它的用法,并计划转化巨大的文档树:doc2dash 在 PyPy 上的速度是在 CPython 上的两倍。
构建文档

接下来是最大的问题——也是一个经常性的 doc2dash 特性请求来源:你需要完整的、构建好的文档。通常,这意味着你必须在安装 doc2dash 之前下载存储库,并弄清楚如何构建文档,因为很遗憾,大多数文档网站都不提供完整文档的下载。

我的做法是首先查找 tox.ini 或 noxfile.py,看看它是否构建文档。如果没找到,就查找 readthedocs.yml,如果还是没有,就找像 docs-requirements.txt 这样的文件或者可选安装目标,如 docs。最后的希望是浏览长长的 YAML 文件,检查 CI 配置。

在安装好所有依赖项后,剩下的工作就只有在文档目录中运行 make html 命令了。

上述工作完成以后,对于 Sphinx ,会生成一个 _build/html 目录,对于 MkDocs,则会生成一个 site 目录。

对于 MkDocs,请注意,如果项目没有使用 mkdocstrings 扩展——唉,现在几乎所有流行的项目皆是如此——就不会有 objects.inv 文件,也没有可供消费的 API 数据。

我真得希望,将来更多基于 MkDocs 的项目添加 mkdocstrings 支持。至于 Sphinx,它是语言无关的。

转换

最难的步骤已经完成,现在轮到最简单的了:将刚刚构建的文档转换为一个 docset。

你所需要做的就只是将包含 HTML 文档的目录提供给 doc2dash,并等待:

$ doc2dash _build/html

就是这样!

doc2dash 知道如何从 intersphinx 索引提取名称,并且默认会使用这个名称(你可以通过 --name 覆盖)。现在,你应该可以将这个 docset 添加到你选的 API 浏览器中了,应该是一切都可以工作了。

如果你传递了 --add-to-dash 或 -a 参数,那么在转换完成后,最终的 docset 会自动添加到 Dash。如果你传递了 --add-to-global 或 -A 参数,那么 doc2dash 会将生成的 docset 移到一个全局目录(类似~/Library/Application Support/doc2dash/DocSets),并从那里添加它。我自己在创建 docsets 时,一般都会使用 -A 运行 doc2dash。

改进文档集

对于通过上述步骤创建的 docset ,Dash 官方文档提供了一系列的改进建议。务请注意,接下来的 5 个步骤不是必须的,我多半会跳过,因为我很懒。

但对于这个项目,我想把 docset 提交到 Dash 的用户文档集注册中心,所以我会走完全程。

设置主页

使用 Dash,你总是可以搜索所有已安装的文档,但有时候,你可能想要限制搜索范围。例如,当我输入 p3: (冒号是有意义的),就会切换为仅搜索 Python 3 文档集。在你开始输入之前,它会在搜索框下提供一个菜单,菜单第一项为“主页”。

在转换 structlog 文档时,主页是可能有用的索引,但通常不是我想要的。当打开主页时,我希望浏览叙述性文档。

用于设置主页的 doc2dash 选项是 --index-page 或 -I ,你想使用哪个页面,就需要提供该页面相对于文档根目录的文件名。

令人困惑的是,索引文件名是 genindex.html,而主页文件名是 HTML 中比较典型的 index.html。因此,我们要在命令行中加入 --index-page index.html。

添加图标

文档可以有图标,在 Dash 中显示在 docset 名称和符号旁。这样既好看,又能帮我们更快地识别文档集,比如,当你跨多个文档集搜索时,就可以知道符号来自哪里。

structlog 有一个可爱的河狸 Logo,因此,我们使用 ImageMagick 将其大小调整到 16x16 像素:

$ magick \    docs/_static/structlog_logo_transparent.png \    -resize 16x16 \    docs/_static/docset-icon.png

现在,我们可以使用 --icon docset-icon.png 选项将其添加到文档集了。

支持在线重定向
离线文档很棒,但有时候,你在阅读文档时可能会需要跳转到在线版本。一个常见的原因是希望阅读新一些的或旧一些的版本。

为此,Dash 提供了一个菜单项“Open Online Page ⇧⌘B”,但你需要提供文档的基地址。可以使用 --online-redirect-url 或 -u 设置。

对于 Read the Docs 网站的 Python 程序包,你可以在 stable (上一个 VCS 标签)和 latest (当前主分支)之间做出选择。

如果你要从离线文档转到在线文档,我觉得 latest 更有意义,因此,我加了下面这个选项:

--online-redirect-url https://www.structlog.org/en/latest/
组合各命令行选项

完成了!让我们运行下整个命令行,在 Dash 中看下效果:

$ doc2dash \    --index-page index.html \    --icon docs/_static/docset-icon.png \    --online-redirect-url https://www.structlog.org/en/latest/ \    docs/_build/htmlConverting intersphinx docs from '/Users/hynek/FOSS/structlog/docs/_build/html' to 'structlog.docset'.Parsing documentation...Added 238 index entries.Patching for TOCs... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00

非常赞:

structlog 的主页

注意搜索栏中的图标,在任何带有锚点的页面上按下⇧⌘B,就会进入到最新版在线文档的同一位置。

自动创建文档集

由于我想每次发布时都创建一个新版本的文档集,所以需要将创建过程自动化。structlog 已经使用 GitHub Actions 实现了 CI,因此,顺理成章地,我也就用它构建文档集了。

对于本地测试,我将利用 doc2dash 作为 Python 项目的便利,使用 tox 环境,它重用了我在测试文档本身时使用的依赖项。

tox 结合了 Makefile 和基于 ini 文件格式的虚拟环境管理器。其初衷是在多个 Python 版本上测试 Python 软件,但现在已经变强了许多。

与 Makefile 相比,它最大的优点是更便于移植,并且自带 Python 打包支持(这对于构建文档来说是必要的)。

该环境安装了 structlog[docs] ,即带有可选 docs 依赖项的程序包,还有 doc2dash 命令。然后,它会依次行 commands:

[testenv:docset]extras = docsdeps = doc2dashallowlist_externals =    rm    cp    tarcommands =    rm -rf structlog.docset docs/_build    sphinx-build -n -T -W -b html -d {envtmpdir}/doctrees docs docs/_build/html    doc2dash --index-page index.html --icon docs/_static/docset-icon.png --online-redirect-url https://www.structlog.org/en/latest/ docs/_build/html    cp docs/_static/[email protected] structlog.docset/[email protected]    tar --exclude='.DS_Store' -cvzf structlog.tgz structlog.docset

现在,我只需调用 tox -e docset 就可以构建文档集。在 doc2dash 支持高分辨率图标之后,它也会直接将一个 32x32 像素的 Logo 复制到文档集中。

在 CI 中做这项工作很简单,但需要大量的样本文件,所以我将直接链接到工作流。注意最后的 upload-artifact 动作,它允许我从运行总结中下载构建好的文档集。

至此,我们已经有了一个很棒的、可以自动构建的文档集。是时候分享给其他人了!

提交

在最后一步中,我们将把构建好的文档集提交到 Dash 的用户文档集存储库,这样,其他人就可以从 Dash 的 GUI 中轻松地下载了。而且比较方便的是,在整个过程中,Dash 使用了一个每个开源爱好者可能都很熟悉的概念:GitHub pull 请求。

第一步是检查文档集贡献清单(Docset Contribution Checklist)。幸运的是,我们(有时候是 doc2dash)已经把一切都处理好了!

好了,让我们继续,创建 https://github.com/Kapeli/Dash-User-Contributions 存储库分叉,克隆到本地计算机上。

首先,你必须将 Sample_Docset 目录复制到 docsets ,并在这个过程中进行重命名。对于我来说,命令行如下:

使用 cd docsets/structlog 进入该目录,在那里继续下一步的工作。

主要步骤是添加文档集本身,但是作为一个 gzipped tar 文件。贡献指南甚至为我们提供了创建压缩包的模板。对于我来说,命令行如下:

$ tar --exclude='.DS_Store' -cvzf structlog.tgz structlog.docset

你可能已经注意到,我已经在 tox 文件中完成了 tar,因此,只需复制过来即可:

$ cp ~/FOSS/structlog/structlog.tgz .

此外,它还要求图标要和 docset 中的一样,所以我从中复制了它们:

$ cp ~/FOSS/structlog/structlog.docset/icon* .

接下来,我们需要在 docset.html 文件中填写元数据,就我这个情况来说很简单:

{    "name": "structlog",    "version": "22.1.0",    "archive": "structlog.tgz",    "author": {        "name": "Hynek Schlawack",        "link": "https://github.com/hynek"    },    "aliases": []}

最后,我们需要编写一些文档,说明我们是谁,以及如何构建 docset。看了其他一些例子后,我确定了以下内容:

# structlog
<https://www.structlog.org/>
Maintained by [Hynek Schlawack](https://github.com/hynek/).

## Building the Docset
### Requirements
- Python 3.10- [*tox*](https://tox.wiki/)

### Building
1. Clone the [*structlog* repository](https://github.com/hynek/structlog).2. Check out the tag you want to build.3. `tox -e docset` will build the documentation and convert it into `structlog.docset` in one step.

tox 技巧发挥作用了——我不必向任何人解释 Python 打包了!

记着从示例 docset 中删掉我们不再用的东西:

$ rm -r versions Sample_Docset.tgz

完成了!提交变更:

$ git checkout -b structlog$ git add docsets/structloggit commit -m "Add structlog docset"[structlog 33478f9] Add structlog docset 5 files changed, 30 insertions(+) create mode 100644 docsets/structlog/README.md create mode 100644 docsets/structlog/docset.json create mode 100644 docsets/structlog/icon.png create mode 100644 docsets/structlog/icon@2x.png create mode 100644 docsets/structlog/structlog.tgz $ git push -u

看起来不错,是时候提交 pull 请求了。

数小时后:

在 Dash 中查看我们贡献的 structlog docset!

非常成功:现在任何人都可以下载 structog 文档集了。我们这份简短的教程到此也就结束了。

总结

希望我这篇文章既激发了你对 API 文档浏览器的兴趣,又让你了解了自己创建文档集的奥秘。我的目标是帮助像我一样的程序员提速,我们在完成工作时需要记忆的软件包太多了。

不过,我最大的愿望是,这篇文章能激励一些人来帮助我向 doc2dash 添加更多的格式,这样,就有更多的程序员能够享受到在弹指间查询 API 文档的乐趣。

在过去的十年中,我在 doc2dash 推广方面做得很糟,希望接下来的十年我能做得更好!

声明:本文为 InfoQ 翻译,未经许可禁止转载。

原文链接:

https://hynek.me/articles/productive-fruit-fly-programmer/

你也「在看」吗? 👇

文章引用微信公众号"AI前线",如有侵权,请联系管理员删除!

博客评论
还没有人评论,赶紧抢个沙发~
发表评论
说明:请文明发言,共建和谐网络,您的个人信息不会被公开显示。