- 数据分析
- CLI
- 数据可视化
【免费下载链接】visidata
A terminal spreadsheet multitool for discovering and arranging data
导读
VisiData 是一个终端表格数据探索工具,其内置帮助体系(GuideSheet 指南、manpage、侧边栏帮助字符串)全部以 Markdown 与一种自定义的"显示属性语法"撰写,再在运行时由MissingAttrFormatter与CommandHelpGetter/OptionHelpGetter动态渲染。本文以仓库中的 dev/DOCS.md 为骨架,结合 visidata/guide.py、visidata/man/vd.inc 与visidata/guides/下真实指南文件,完整讲解 VisiData 文档的语法、模板、写作约定与构建流程,帮助你为 VisiData(或其插件)编写风格一致、可被 GuideSheet 正确渲染并进入 manpage 的内置帮助文档。
一、文档体系总览:一份源码,三处呈现
VisiData 的内置文档遵循"单一来源、多端呈现"的设计,这一点在dev/DOCS.md开头即有明确说明:
docs/man.md由 manpage 源文件(visidata/man/vd.inc)经dev/mkman.sh生成。修改时应编辑vd.inc,而非生成的man.md。
从仓库实际结构看,文档体系分为三层:
| 层 | 源文件 | 呈现位置 |
|---|---|---|
| manpage | visidata/man/vd.inc | 构建产物vd.1、visidata.1、vd.txt,可用g^H在 VisiData 内查看 |
| GuideSheet 指南 | visidata/guides/*.md | VisiData 内置的 Guide Index(Space打开)中的各篇指南 |
| helpstring / 侧边栏 | 散落在visidata/*.py各命令与选项定义处 | 命令帮助、Options Sheet 等 |
其中指南文件采用 Markdown +{help.commands.*}、{help.options.*}占位符,与 manpage 的 roff 源完全分离但语义互补。dev/DOCS.md中"VisiData 支持基本 Markdown(# Headings、bold、italics、code snippets、underscore)"一条,正是针对 GuideSheet 指南而言。
二、核心语法一:显示属性(Display Attribute)标记
VisiData 有自己的显示属性语法,用于在纯文本文档中注入可交互、带颜色的富文本。dev/DOCS.md给出了两个规范示例。
2.1 可点击链接
[:onclick <url>]<text>[/]将<text>格式化为可点击 URL,点击后会在$BROWSER中打开。仓库中的真实用法,例如 visidata/guide.py 的 Guide Index 简介:
We love contributions: [:onclick https://visidata.org/docs/api/guides]https://visidata.org/docs/api/guides[/].2.2 颜色与语义色
[:red on black]<sentence>[/]将<sentence>渲染为黑底红字。:之后可以使用任意颜色选项,例如[:warning]、[:error]、[:menu]。dev/DOCS.md特别强调:
尽可能使用
[:semantic_color]而非硬编码颜色。
这对应 VisiData 的主题/语义色机制:在 GuideSheet 与帮助文本中,语义色会跟随用户主题,而硬编码颜色不会。仓库中常见的语义色标记还包括[:keystrokes]、[:longname_guide]、[:code]、[:onclick]等,例如 visidata/guide.py 中动态生成的命令条目:
[:code]{binding}[/] ([:longname_guide]{longname}[/]) to {helpstr}三、核心语法二:{vd.options.*}选项值内联
VisiData 会替换{vd.options.disp_selected_note}为当前选项值——例如disp_selected_note的默认值是+。任何选项值都可以用{vd.options.optname}引用。
dev/DOCS.md给出了这条规则的动机:
这是确保正确选项被展示的好办法,即使使用者已经修改了选项值。
也就是说,文档中不要写死+、:这类符号,而应通过占位符引用选项,让文档随用户配置自适应。这一替换由 visidata/utils.py 的MissingAttrFormatter完成——它继承自string.Formatter,在字段缺失时不会抛KeyError/AttributeError,而是原样保留{field_name}(见utils.py#L195-L199),从而避免因选项重命名导致的渲染崩溃。
四、核心语法三:{help.commands.*}与{help.options.*}模板
这是 GuideSheet 文档最核心的机制:不要在指南里手写按键与帮助字符串,而是用占位符让系统生成。
4.1 命令占位符
dev/DOCS.md规定,命令应使用{help.commands.longname}展开为如下规范格式:
- `<keystroke>` (`<longname>`) to <command helpstring>.对应实现位于 visidata/guide.py 的CommandHelpGetter:它通过__getattr__接收占位符中的 longname,在HelpSheet的反向绑定表(revbinds)中查找实际按键,再拼接命令帮助字符串;若命令接收输入,还会追加<input>或具体输入类型。例如 visidata/guides/MovementGuide.md 中的一行:
- {help.commands.go_down}渲染后即成为↓ (go_down) to move cursor down one row.这类条目。按键紧跟项目符号,规范中明确:
keystroke 紧跟在 bullet 之后。VisiData 文档与 helpstring 中不要说 "Press" 或 "Use"。
4.2 选项占位符
选项应使用如下模式列出(dev/DOCS.md原文):
- [:onclick options-sheet <option name>]`<option name>`[/] to <option helpstring> (default: <option default value>).同样地,更推荐用{help.options.option-name}展开,而不是手写。实现见 visidata/guide.py 的OptionHelpGetter:
return f'[:onclick options-sheet {optname}][:longname_guide]{optname}[/][/]: {opt.helpstr} (default: {opt.value})'它把选项名变成指向 Options Sheet 的可点击链接,并自动附带帮助字符串与当前默认值。真实示例,如 visidata/guides/FrequencyTable.md:
- {help.options.disp_histogram} - {help.options.histogram_bins} - {help.options.numeric_binning}4.3 渲染流水线
GuideSheet 的加载逻辑(visidata/guide.py)展示了完整流水线:
- 读取
visidata/guides/<Name>.md源文本; - 按
---解析 front matter(如sheettype元数据,用于确定命令查找的 Sheet 类); - 构造
helper = AttrDict(commands=CommandHelpGetter(...), options=OptionHelpGetter()); - 用
MissingAttrFormatter().format(guidetext, help=helper, vd=vd)展开全部{help.*}占位符; - 按 78 列折行(
wraptext)后逐行进入 GuideSheet 表格。
五、写作风格规范
dev/DOCS.md后半部分是一组精炼的写作约定,是评审 VisiData 文档提交的核心 checklist:
| 规范 | 说明 |
|---|---|
| 人称 | 教程之外的文档不得使用第二人称("you"/"yours") |
| 语境 | 不写 "In VisiData",默认用户已在 VisiData 内 |
| 用词 | 不使用多余的填充词;用更简单的词与语法,面向 ESL 读者;动词用不定式,避免将来时与条件句;用主动语态 |
| 术语 | 使用既定词汇,如 "command" 而非 "operation"/"action" |
| 语义色 | 能用[:semantic_color]就不用硬编码颜色 |
| 按键样式 | 指南中用户会实际输入的内容(keystroke、longname、CLI 选项)用[:keystrokes];用户看到的输出不用 |
| 修饰键 | 写作Ctrl+X、Alt+X、Shift+X,禁用脱字符记法(^X) |
| 前缀键 | 前缀修饰键与基础键之间用空格分隔:g Enter、z Shift+F、gz Enter |
| 选项名 | 行文中选项名加options.前缀(如options.numeric_binning);选项表中列头已写 "option" 时不加 |
| 详略 | 匹配周围条目的详细程度;loader 参考新增通常只需命令摘要 |
| 描述对象 | 描述用户可见行为而非实现细节。例如写 "在频率表上撤销也会在源表上撤销",而非 "两张表共享同一个撤销点" |
| 表格 vs 列表 | 每行可独立成条时优先用列表,而非多列表格 |
| 标点 | 仅用 ASCII 标点;禁用 em-dash、en-dash、弯引号、Unicode 省略号,用-或: |
| 标题 | 小节标题用简短名词短语或祈使句(如 "Sort by one column"、"Hide and Unhide columns"),不用完整句子或 "How to X" 式标题 |
| 开场白 | 标题自解释时跳过开场段;最多一句简短 setup |
| 描述内容 | 描述命令做什么,而非界面长什么样("屏幕底部出现提示"属于 UI 叙述,应避免) |
| 模糊语 | 避免 "(when available)"、"(if possible)" 这类含糊括注 |
这些约定在 visidata/guides/ColumnsGuide.md 中有很好的示范——其小节标题均为名词短语("Resize the current column"、"Hide and Unhide columns"),全文无第二人称,选项与命令均通过占位符引用。
六、manpage 生成链路:vd.inc→mkman.sh
6.1 构建流程
dev/mkman.sh 是 manpage 的生成脚本(通过make man触发),其关键步骤为:
- 将
visidata/man/下的 roff 源复制到/tmp/visidata_manpages构建目录; - 运行 visidata/man/parse_options.py,从
visidata.options运行时注册表中扫描所有选项,自动生成vd-cli.inc(CLI 选项段)与vd-opts.inc(显示选项段)两个 roff include; - 用
soelim -rt -I展开vd.inc中的.soinclude,得到vd-pre.1; - 用
preconv(UTF-8 转换)生成vd.1与visidata.1; - 用
man渲染出vd.txt。
脚本头部还注明了外部依赖:soelim、preconv(来自 groff)与man。
6.2 选项自动扫描
parse_options.py展示了 manpage 中 CLI 选项如何与源码保持同步:它遍历visidata.options的全部键,读取每个选项的名称、类型、默认值与 helpstring,按bool与其他类型分别套用 roff 模板。由此可以推断:新增/修改选项的 helpstring 后重新运行构建,manpage 会自动反映变更,无需手工维护选项列表。
6.3 主源文件结构
visidata/man/vd.inc 是手写的 roff 主源,涵盖:
- SYNOPSIS:普通启动、
--play回放模式、以及+toplevel:subsheet:col:row光标定位启动语法; - GLOBAL COMMANDS:从退出(
^Q、q、Q、gq)、移动(h/j/k/l、G/gg、^B/^F、zz)、搜索(/、?、n/N、z/表达式搜索)到列操作、行选择、排序、编辑、数据工具包、可视化与分屏命令的完整按键参考; - INTERNAL SHEETS / METASHEETS / DERIVED SHEETS:Directory Sheet、Guide Index、Memory Sheet、Columns Sheet(
Shift+C)、Sheets Sheet(Shift+S)、Options Sheet(Shift+O)、CommandLog(Shift+D)、Threads Sheet(Ctrl+T)、Frequency Table(Shift+F)、Describe Sheet(Shift+I)、Pivot Table(Shift+W)、Melted Sheet(Shift+M)等; - COMMANDLINE OPTIONS:
-f/--filetype、-of、-d、-y/--confirm、-ro/--overwrite、-N/--nothing、-P=longname(preplay)、+sheet:col:row定位、--guides等,随后.so vd-cli.inc引入自动生成的完整 CLI 选项; - EXAMPLES:
vd foo.tsv、vd -f ddw、vd -f sqlite bar.db、vd -b countries.fixed -o countries.tsv(格式转换)、--play回放、管道ls -l | vd -f fixed --skip 1 --header 0、多文件光标定位等实用示例; - FILES:
$HOME/.visidatarc启动时被exec(),可设置选项、bindkey、定义函数并经vd.aggregator()注册聚合器; - SUPPORTED SOURCES:tsv、csv、fixed、json/jsonl、sqlite、http 及 zip/gz/bz2/xz/zstd 在线解压。
这些内容与dev/DOCS.md共同构成 VisiData 的完整内置文档体系——前者是书写规范,后者是内容本体。
七、撰写一份合规指南的实操流程
结合上述规范,为 VisiData 新增或修订一篇指南(或插件自带指南)的推荐流程为:
- 选型:在 visidata/guides/ 下新建
<GuideName>.md,或在插件包内附带同名文件;GuideSheet 通过vd.addGuide(name)从visidata/guides/{name}.md加载(visidata/guide.py); - 搭骨架:用
#标题开篇,小节标题使用名词短语或祈使句;标题自解释时不要写开场段; - 引用命令:凡涉及按键/命令,一律写
- {help.commands.<longname>},不要手写按键——渲染器会从 HelpSheet 自动匹配当前按键绑定; - 引用选项:写
- {help.options.<opt-name>},渲染为带默认值、可点击跳转 Options Sheet 的条目; - 富文本:需要链接时用
[:onclick <url>]<text>[/];需要强调时用语义色[:warning]、[:error]、[:menu]而非硬编码颜色;用户会键入的内容用[:keystrokes]包裹; - 语言自检:无第二人称、无 "In VisiData"、无填充词、动词不定式、主动语态、全 ASCII 标点;
- 验证:启动
vd,用Space打开 Command Palette 执行open-guide-index,进入新指南查看{help.*}是否正确展开;修改 visidata/man/vd.inc 后运行make man重新生成 manpage。
参考来源
- 规范正文:dev/DOCS.md
- 渲染实现:visidata/guide.py、visidata/utils.py
- 指南样例:visidata/guides/MovementGuide.md、visidata/guides/ColumnsGuide.md、visidata/guides/FrequencyTable.md、visidata/guides/ClipboardGuide.md
- manpage 生成:dev/mkman.sh、visidata/man/vd.inc、visidata/man/parse_options.py
- 数据分析
- CLI
- 数据可视化
【免费下载链接】visidata
A terminal spreadsheet multitool for discovering and arranging data
相关推荐
FSPagerView代码文档规范:编写易读易维护的API文档
FSPagerView代码文档规范:编写易读易维护的API文档 在iOS开发中,优雅的轮播图(Banner View)和页面滑动组件是提升用户体验的关键元素。F
移动开发UI组件Zinx代码注释规范:提升可维护性的文档编写指南
Zinx代码注释规范:提升可维护性的文档编写指南 引言:为什么注释规范对Zinx至关重要? 你是否曾打开一个开源项目,却因混乱的注释而无从下手?作为基于Gola
后端Pydantic AI 文档编写规范:为读者价值写作的文档、Docstring 与代码注释指南
Pydantic AI 文档编写规范:为读者价值写作的文档、Docstring 与代码注释指南 本文是 Pydantic AI 仓库内部《Documentati
人工智能大模型AI Agent工具调用MCP Clients
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考