- 开发工具
【免费下载链接】enquirer
Stylish, intuitive and user-friendly prompts. Used by eslint, webpack, yarn, pm2, pnpm, RedwoodJS, FactorJS, salesforce, Cypress, Google Lighthouse, Generate, tencent cloudbase, lint-staged, gluegun, hygen, hardhat, AWS Amplify, GitHub Actions Toolkit, @airbnb/nimbus, and more! Please follow Enquirer's author: https://github.com/jonschlinkert
Enquirer 是一个以"会话感"为核心设计理念的 Node.js CLI 交互提示符库,本篇文章围绕仓库内 support/cheatsheet.md 这份速查表展开,系统梳理 Enquirer 的领域术语(Terminology)、按键绑定(Keypresses)、样式调色板(Styles)、状态机(State/Status)与事件体系(Events)。读完本文,你将能读懂 Enquirer 源码中的命名约定,能自定义样式与符号,能理解每种按键在底层被映射到哪个提示符方法,并能在测试或插件开发中正确监听state、submit、cancel等事件。
术语体系:用 HTML/CSS 的直觉理解提示符
Enquirer 在设计上刻意借用了 Web 开发者熟悉的 HTML/CSS 概念来描述提示符的行为与属性,这样可以大幅降低理解成本。下表是速查表中给出的核心术语,它们在源码(如 lib/roles.js、lib/state.js)中均有对应的具体实现:
| 术语 | 说明 |
|---|---|
focused | 当前被瞄准的选项,仅存在于可见的选项列表中,概念上等价于 HTML/CSS 中的 focus。 |
pointer | 标记当前获得焦点的选项。通常用❯符号表示,但指针并不总是可见的,例如autocomplete提示符就隐藏指针。 |
indicator | 表示某个选项是否被选中/启用。 |
index | 指针在可见选项列表中的零基位置。 |
cursor | 光标相对用户输入内容的零基位置。 |
selected | 当前选项所处的位置。 |
enabled | 当前选项所处的位置。 |
active | 当前选项所处的位置。 |
element | 提示符的各个组成部分,一个元素可以由样式、文本和 Unicode 符号组合而成。 |
其中indicator、separator、heading等概念在 lib/roles.js 中被实现为"角色(role)"函数:例如heading角色会清空选项的disabled、补全indicator,separator角色则默认用prompt.symbols.line重复 5 次生成分隔线。这些角色函数决定了某个选项在提示符中如何呈现,是理解 Enquirer 渲染管线的重要入口。
元素(Elements):提示符的拼装积木
速查表明确指出:元素(Element)是一个函数,其职责是基于提示符的 state 与 status,把样式、文本和 Unicode 符号组合起来,渲染出提示符的某一个具体部分。
速查表列出的核心元素包括:
prefix:提示符前缀,通常展示状态标记。在 lib/symbols.js 中,前缀符号是按状态区分的:pending用问号、submitted用对勾、cancelled用叉号。message:开发者自定义的提示文案,在样式系统中由strong(加粗)样式渲染。separator:分隔元素,同样在 lib/symbols.js 中按状态区分符号(pointerSmall/middot)。indicator:选中状态指示符,例如复选框中已选/未选/禁用的三种图形。
从源码结构看,元素渲染依赖state中header、footer、hint、error等字段(见 lib/state.js 构造函数中对这些字段的初始化),并通过 lib/prompt.js 的sections()、render()等流程输出到终端。
转换器(Transforms):格式化用户输入的钩子
速查表将Transforms定义为"由render函数与result函数组成的对象",它们同样基于提示符的 state 与 status 工作:
render负责在提示符运行期间如何格式化显示用户输入(例如数字格式化为货币、时间格式化为日期)。result负责在提示符提交之后如何转换最终值(例如把字符串解析为数字或对象)。
这与 lib/prompt.js 中submit()流程里this.value = await this.result(this.value)的调用链完全吻合:先render展示、后result定值。在 examples/number/option-format.js、examples/input/option-state.js 等示例中可以看到format、result组合使用的真实案例。
状态与状态机:pending / answered / cancelled
速查表把State与Status单列为一条:
- state:包含渲染提示符每一部分所必需的属性(message、header、footer、input、cursor、index、buffer、width 等),由 lib/state.js 中的
State类实现,并提供了clone()方法用于把状态快照分发给事件监听者。 - status:提示符的三种状态之一——
pending(等待输入)、answered(已作答)、cancelled(已取消)。在 lib/state.js 中实际以get status()实现:cancelled优先、其次submitted、其余为pending。
结合 docs/state.md 与 docs/prompt-events.md 可以进一步理解:每次按键都会触发一次state事件并携带 state 快照,这是编写单元测试与自定义渲染逻辑的基础。
按键绑定(Keypresses)
全局命令键
以下按键组合在所有提示符中生效(速查表原文):
| 按键 | 说明 |
|---|---|
| ctrl+a | 将光标移到用户输入的第一个字符。 |
| ctrl+c | 取消提示符。 |
| ctrl+d | 取消提示符。 |
| ctrl+g | 将提示符重置为初始状态。 |
| ctrl+l | 将提示符重置为初始状态。 |
| ctrl+r | 从提示历史中移除当前值(在支持历史记录的提示符中)。 |
| ctrl+s | 将当前值保存到提示历史(在支持历史记录的提示符中)。 |
| ctrl+z | 撤销上一次操作(在支持撤销的提示符中)。 |
这些按键映射与 lib/combos.js 中exports.ctrl的映射表可以相互印证,例如a: 'first'、g: 'reset'、l: 'reset'、r: 'remove'、s: 'save'、u: 'undo'、c: 'cancel'。需要留意的是,速查表将ctrl+d描述为"取消",而当前仓库源码 lib/combos.js 中d映射为deleteForward(删除光标后的字符),两者存在细微差异——以你在当前版本中的实际行为为准,按键行为可通过options.actions自定义覆盖(见 lib/prompt.js 中keypress()对this.options.actions的处理)。
光标移动
以下按键适用于所有支持用户输入的提示符(速查表原文):
| 按键 | 说明 |
|---|---|
| ctrl+a | 光标移动到行首 |
| ctrl+e | 光标移动到行尾 |
| ctrl+b | 光标回退一个字符 |
| ctrl+f | 光标前进一个字符 |
| ctrl+x | 在首位置与光标位置之间切换 |
| left | 光标前进一个字符 |
| right | 光标回退一个字符 |
Windows 补充(速查表标注为 "Not implemented yet"):
| 按键 | 说明 |
|---|---|
| alt+b | 光标回退一个单词 |
| alt+f | 光标前进一个单词 |
在 lib/combos.js 中可以看到对应实现:b: 'backward'、f: 'forward'、e: 'last'、x: 'toggleCursor',而exports.option中b: 'backward'、f: 'forward'正是速查表中 Windows/Alt 组合键的映射。
数组类提示符的按键(Array Prompt Keypresses)
数组类提示符(如multiselect、form、sort等基于 lib/types/array.js 的提示符)拥有独立的按键体系:
| 按键 | 说明 |
|---|---|
| a | 将所有选项切换为启用或禁用。 |
| i | 反转当前选项的选择状态。 |
| g | 切换当前选项组。 |
| space | 当options.multiple为 true 时,切换当前选中选项。 |
显示/隐藏选项
| 按键 | 说明 |
|---|---|
| fn+up | 可见选项数减少一个。 |
| fn+down | 可见选项数增加一个。 |
移动指针
| 按键 | 说明 |
|---|---|
| number | 将指针移动到指定索引的选项;当options.multiple为 true 时同时切换该选项。 |
| up | 指针上移。 |
| down | 指针下移。 |
| ctrl+a | 指针移动到第一个可见选项。 |
| ctrl+e | 指针移动到最后一个可见选项。 |
| (mac)fn+left/ (win)home | 指针移动到选项数组的第一个选项。 |
| (mac)fn+right/ (win)end | 指针移动到选项数组的最后一个选项。 |
| shift+up | 向上滚动一个选项,不改变指针位置。 |
| shift+down | 向下滚动一个选项,不改变指针位置。 |
这些映射同样可以在 lib/combos.js 中一一对应:exports.keys中pageup: 'pageUp'、home: 'home'、end: 'end'、number: 'number'、space: 'space',exports.shift中up: 'shiftUp'、down: 'shiftDown'。完整的按键绑定文档见 docs/key-bindings.md,也可运行 examples/prompt-navigation.js 实际体验导航行为。
样式系统(Styles):语义化颜色
什么是样式
速查表定义:样式(Styles)是语义命名的函数,用于通过 ANSI 样式代码为提示符的各元素添加颜色。底层由ansi-colors库实现(见 lib/styles.js 顶部的require('ansi-colors'))。
默认调色板
速查表给出的默认调色板(Name / Default colors / Description)如下:
| 名称 | 默认颜色 | 用途 |
|---|---|---|
primary | cyan | 用于提示符的 indicator、选项 pointer,以及提交后用户输入("答案")的样式。 |
danger | red | 用于错误消息。 |
strong | bold | 用于开发者自定义的 prompt message。 |
success | green | 用于已启用选项的 indicators。 |
warning | yellow | 未使用。 |
muted | dim | 用于提示信息(hints)。 |
disabled | gray | 用于禁用选项的文案。 |
dark | dim.gray | 被其他样式使用。 |
default | noop(不应用任何样式) | 未使用。 |
info | styles.primary | 由 confirm 提示符用于用户输入的样式。 |
inverse | styles.primary的反色 | 未使用。 |
complement | styles.primary的补色 | 未使用。 |
answered | styles.primary | 多个提示符用于提交后的用户输入样式。 |
cancelled | styles.danger | 提示符取消时用于前缀(prefix)的样式。 |
completing | styles.default | 未使用。 |
pending | styles.default | 未使用。 |
on | styles.success | 用于已勾选选项的 indicator。 |
off | styles.dark | 用于未勾选选项的 indicator(单选按钮、复选框、对勾标记等)。 |
active | styles.primary | 用于当前活动元素。 |
selected | styles.active.underline | 用于当前选中元素。 |
placeholder | styles.primary.dim | 用于占位符文本。 |
highlight | styles.inverse | 用于高亮文本。 |
需要补充的是,样式值在源码层面是可推导、可推导覆盖的:打开 lib/styles.js 可以看到调色板由若干可写的 setter/getter 对构成(如info、pending、submitted、cancelled、placeholder、highlight),且存在未写入速查表但实际可用的样式,例如submitted(默认success)、typing(默认dim)、underline、heading等。另外,速查表记录danger默认色为red,而当前仓库源码 lib/styles.js 中danger: colors.magenta——这正是"样式可被覆盖"的体现,实际显示效果以当前安装版本为准。
如何应用样式
如果你是提示符作者,可以通过prompt.styles(在提示符实例内部即this.styles)访问这些样式,其中每个"style"都是一个把返回字符串包裹进 ANSI 代码的函数。例如:
prompt.styles.danger('Something went wrong'); prompt.styles.success('All good');样式会通过 lib/theme.js 的styles.merge(prompt.options)与symbols.merge(prompt.options)合并进每个提示符实例,因此你也可以在创建提示符时通过options.styles覆盖任意样式、通过options.symbols覆盖符号(详见 docs/styles.md 与 docs/symbols.md)。
符号(Symbols)
与样式配套的是 Unicode 符号系统。速查表在 Styling 小节将 Symbols 定义为"Unicode symbols"。在 lib/symbols.js 中可以看到丰富的预置符号,例如:
- 状态化前缀:
prefix.pending(?)、prefix.submitted(✓)、prefix.cancelled(✖); - 单选/复选图形:
radio(◯/◉/Ⓘ,Windows 下退化为( )/(*)/(|))、ballot(☑/☐/☒)、stars(★/☆); - 大量箭头、标点与装饰符号(
⇕、⌁、⋯、¶等),并支持通过options.symbols整体覆盖。
事件体系(Events):与提示符交互的钩子
速查表列出的事件如下:
| 事件 | 说明 |
|---|---|
state | 每次按键都会触发,携带prompt.state对象的一个克隆。 |
alert | 当调用prompt.alert()时触发。用于在终端不可见输出的场景(如单元测试)中检测无效按键。 |
submit | 用户提交时触发,携带答案value。 |
cancel | 提示符被用户终止或抛出错误时触发。 |
close | readline 接口关闭、输入流暂停时触发。 |
run | 提示符初始化完成时触发。 |
源码层面,lib/prompt.js 是这些事件的主要发射方:
keypress()在每次按键时执行this.emit('state', this.state.clone()),与速查表"每次按键都会发出 state 快照"的描述完全一致;alert()在options.show === false时发射alert事件(否则写入终端蜂鸣符ansi.code.beep),这正是速查表"用于单元测试检测无效按键"的用意;submit()在验证通过后执行this.emit('submit', this.value);cancel()执行this.emit('cancel', await this.error(err));close()发射close事件,并在start()中通过this.once('close', this.stop)停止按键监听。
想深入理解每个事件的触发时机与典型用法,可以阅读 docs/prompt-events.md,或参考 test/support/emitter.js 这类测试辅助代码观察事件在测试环境中的实际行为。
速查表之外:把这些知识用起来
这张速查表本质上是 Enquirer 内部架构的"索引",沿着它的条目可以继续深入:
- 想了解所有内置提示符类型与各自选项,见 docs/prompts.md 与 README.md 中的 Built-in Prompts 部分;
- 想基于速查表的概念创建自定义提示符(元素、转换器、样式、事件全部用得上),见 docs/custom-prompts.md 与 examples/enquirer/custom-prompt-class.js;
- 想了解渲染管线(sections、buffer、状态快照如何变成屏幕上的内容),见 docs/rendering.md;
- 想动手试验样式与符号,可参考 examples/select/option-theme.js、examples/input/option-styles.js、examples/input/option-symbols.js。
掌握术语、按键、样式与事件这四张表,你就拥有了阅读 Enquirer 源码、编写自定义提示符与插件所需的全部"词汇表"——这也是这份速查表存在的意义。
- 开发工具
【免费下载链接】enquirer
Stylish, intuitive and user-friendly prompts. Used by eslint, webpack, yarn, pm2, pnpm, RedwoodJS, FactorJS, salesforce, Cypress, Google Lighthouse, Generate, tencent cloudbase, lint-staged, gluegun, hygen, hardhat, AWS Amplify, GitHub Actions Toolkit, @airbnb/nimbus, and more! Please follow Enquirer's author: https://github.com/jonschlinkert
相关推荐
QMK 固件中的 AEKISO60 键盘支持:ISO AEK 键帽 + ALPS 开关 60% PCB 的构建与刷写指南
QMK 固件中的 AEKISO60 键盘支持:ISO AEK 键帽 + ALPS 开关 60% PCB 的构建与刷写指南 导读 AEKISO60 是 4pple
开发工具Xonsh 提示符(Prompt)完全定制指南:两大 REPL 引擎、$PROMPT 字段、颜色系统与自定义按键绑定
Xonsh 提示符(Prompt)完全定制指南:两大 REPL 引擎、$PROMPT 字段、颜色系统与自定义按键绑定 Xonsh 是"Python powere
开发工具Enquirer中的设计模式:观察者模式在事件系统中的应用
Enquirer中的设计模式:观察者模式在事件系统中的应用 观察者模式简介 观察者模式(Observer Pattern)是一种行为设计模式,它允许对象(观察者
开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考