Input Nexus 是一个数据驱动的输入/命令中心,负责候选匹配、历史回溯、占位补全与命令上下文管理,供各种渲染器(TUI、GPUI、Web)复用。
- 逻辑与渲染分离:Input Nexus 仅产出纯数据结构(
CommandSpec、InputState、补全提示等),渲染器负责画面与交互。 - 多来源命令统一管理:通过
CommandContext痕迹不同类型的命令(LLDB、内置、脚本、断点)、前缀和模糊匹配策略。 - 占位/补全驱动:命令模板含可插入占位符(
<addr>/<comment>),Tab 补全可填充默认或提示值,推动专业 IDE 级别的输入体验。 - 历史与 Suggestion:内置历史、搜索、评分机制,保留用户习惯、提供统计后的智能补全。
- 动态可扩展:运行时可以注册新的命令/上下文/脚本入口,任意渲染器可通过 Input Nexus 的 API 读取当前候选并渲染。
- 构建
InputController,并添加已有上下文与命令:use input_nexus::{command_set, InputController, CommandContext}; let mut controller = InputController::new(); controller.register_context(CommandContext::new("internal", "内置命令").with_prefix(":")); controller.register_context(CommandContext::new("debugger", "调试器命令").with_prefix("dbg> ")); for spec in command_set![ "palette" => "internal" => ":palette" => "打开命令面板", "connect" => "debugger" => "connect <url>" => "连接目标", "br_add" => "debugger" => "br add <addr> [comment]" => "添加断点", ] { controller.register_command(spec); }
- 通过
handle_key消费按键事件,驱动InputState、历史、补全。 - 渲染器读取
InputState(当前缓冲、候选列表、占位)以绘制提示、Tab 下划线等。 - 分组/来源展示:
- 每个候选都有
CommandSpec.context_id,渲染器可据此分组(例如lldb/script/internal)。 - 若需要在同一来源内进一步分组,可使用
CommandSpec.group(例如脚本元数据里的group = "aslr")。 - 通过
controller.contexts()/controller.context("lldb")获取上下文的描述、前缀等 UI 元信息。
- 每个候选都有
- 场景:打开命令面板后,先前执行过
br add 0x1000,现在键入br,Input Nexus 返回br add、br del这样的候选。 - 用户操作:按下
Tab,补全br add并自动填充<addr>占位提示,由渲染层显示br add <addr>. - 占位填充:用户输入
0x2000后再次Tab跳转到[comment]占位,默认填入历史评论;此时InputState记录placeholder_bindings,渲染层可在字段下方提示说明。 - 历史搜索:按下向上键即可从历史取出
br add 0x1000,重用之前的参数;另可在 Palette 搜索c,Input Nexus 返回continue、connect等匹配候选,渲染层根据CommandContext进行分组/高亮。 - 完成执行:确认后
Enter,InputController.handle_key返回InputResult::Completed("br add 0x2000 --force"),App将其转发至 LLDB API。
新增 examples/story_tui.rs 提供真正可以交互的 TUI 示例(使用 crossterm + ratatui),可通过 cargo run --example story_tui 体验上述流程;对应的文本版交互脚本见 examples/story.md。
详尽的交互脚本与 story 模式可参见 examples/story.md,便于演示日志与测试。
Tab:从命令候选跳转/切换,或在占位间跳转。Enter:无占位直接完成;占位阶段仅必填占位非空时完成,跳过可选项。Space(占位编辑时):除最后一个占位外,当前占位已填写则跳到下一个占位;在最后一个占位中作为普通输入(允许多词注释/表达式)。Backspace/Delete:按光标删除;在占位开头会自动跳到前一个占位尾部以便继续删除。Left/Right/Home/End:占位编辑阶段在占位内部移动光标;普通阶段移动整行光标。Ctrl+A/Home:行首;Ctrl+E/End:行尾。Ctrl+W:删除光标前一个单词。Up/Down:候选切换、占位选择或历史回溯(取决于当前阶段)。
交互脚本与 story 模式见 examples/story.md。
CommandSpec由模板解析器parse_command_spec生成;推荐使用宏command_spec!或command_set!(批量)从字符串模板构造。register_templates!宏可将模板列表直接注册到InputController,适合初始化时一次加载多条命令;InputController::register_from_template支持 runtime 动态注册。- 动态脚本或 Palette 只需调用
register_from_template或register_command,即可向 controller 插入新的命令/占位并马上生效。
- 通过
cargo test运行InputController的关键路径测试(Tab→选择→占位→回退),确保逻辑稳定; examples/story_tui.rs仍可通过cargo run --example story_tui体验、在logs/input-nexus.log查看 tracing 输出;- Rust Doc 在源码中描述了
InputController/InputState的使用与阶段模型,可通过cargo doc --open阅读更多细节。