banner
约 1,500 字
5 分钟

把常用命令收进一个 TUI:cmdp 让终端工作流更顺手

摘要

cmdp 是一个用 Rust 编写的终端命令模板选择器:把常用命令、参数、危险确认和项目专属工作流收进一个 TUI,让复杂命令不再靠记忆和复制粘贴。

有些命令不是不会写,而是每次写都让人停顿一下。

比如 find 查大文件、cargo clippy --all-targets -- -D warningsjournalctl -u xxx -b -n 100 --no-pager,还有一堆带可选参数、路径、重定向、危险操作的长命令。它们都不难,但足够琐碎:少一个引号、漏一个参数、忘了某个 flag,就要重新查一遍历史记录。

cmdp 想解决的就是这个问题:把这些命令沉淀成模板,然后用一个终端 TUI 来选择、填写、预览和执行。

它不是命令别名,而是命令工作台

传统 alias 适合特别短、特别固定的命令。一旦命令需要参数、开关、分类、危险提示,alias 就开始变得别扭。

cmdp 的做法更接近一个“命令工作台”:

  • 左侧选择分类,比如 Git、Rust、文件搜索、systemd。

  • 中间选择具体命令。

  • 右侧填写参数、切换可选片段。

  • 底部实时预览最终会执行的 shell 命令。

  • 确认后退出 TUI,恢复终端,再在原终端里执行命令。

这点很重要:命令输出不会被塞在 TUI 里,也不会丢失终端状态。执行前程序会关闭 raw mode、退出 alternate screen,并把 stdout/stderr/stdin 交还给真实 shell 子进程。

用户界面
用户界面

配置就是 TOML

cmdp 不内置命令,也不会偷偷生成固定模板。它运行时读取配置:

纯文本
~/.config/cmdp/*.toml

全局配置按文件名排序加载;进入某个项目后,还会从当前目录向上查找 .cmdp.toml。本地配置最后加载,所以可以覆盖全局同名命令,也可以追加项目专属命令。

这让它很适合两类场景:

  • 全局命令:Git、Rust、文件查找、压缩解压、Flatpak、systemd。

  • 项目命令:当前仓库的测试、发布检查、安装、版本查看、打 tag。

一个最小命令模板大概长这样:

toml
[categories.rust]
alias = "Rust"

[commands.cargo_test]
category = "rust"
title = "Cargo Test"
description = "运行 Rust 测试"
danger = false
template = '''
cargo test [[locked:--locked]] [[test_name:{{test_name}}]] [[nocapture:-- --nocapture]]
'''

params = [
  { name = "test_name", label = "测试名", placeholder = "parser" },
]

options = [
  { id = "locked", label = "锁定 Cargo.lock", default_enabled = false },
  { id = "test_name", label = "只运行指定测试", default_enabled = false },
  { id = "nocapture", label = "显示测试输出", default_enabled = false },
]

{{name}} 是参数占位符,[[id:...]] 是可选片段,<<...>> 是必填片段。可选片段关闭时,里面的参数不会被要求填写;打开后才参与缺失参数校验。

对危险命令更谨慎一点

很多工具最让人担心的不是“能不能执行”,而是“会不会太容易执行”。

所以 cmdp 支持 danger = true。这类命令不会一次确认就直接跑。第一次执行只会在 TUI 里显示危险确认提示;再次确认同一个渲染后的命令才会真正退出 TUI 并执行。

切换命令、修改参数、切换选项或搜索变化,都会取消这次确认。

这不是绝对安全,但它能挡住很多手滑。

模板可以处理真实 shell 写法

最近我专门补了对重定向写法的说明和测试。>, >>, <, 2>, 2>> 都可以作为普通模板文本使用:

toml
template = '''
sort < <<"{{input}}">> > <<"{{output}}">> [[log:2>> "{{log}}"]]
'''

推荐把重定向符写在模板文本里,只把文件路径做成参数。不要把 >> 塞进 <<...>> 必填片段内部,因为 <<...>> 本身就是 cmdp 的片段语法。

我最喜欢的部分:配置可以长出来

cmdp 的示例配置已经拆成了多个主题文件:Git、Rust、搜索、文件查看、大小统计、systemd、Flatpak、DNF、压缩解压,甚至还有一组光盘刻录/ISO 校验相关模板。

这些模板不是必须安装的默认值,而是一个模板库。想用哪些,就复制哪些到 ~/.config/cmdp/

sh
mkdir -p ~/.config/cmdp
cp -n examples/git.toml examples/rust.toml ~/.config/cmdp/

这比“一个巨大配置文件”更容易维护,也更符合真实工作流:今天你只需要 Git 和 Rust,明天需要 systemd,再加一个文件就行。

适合谁

如果你经常在终端里工作,并且已经开始维护自己的脚本、alias、README 命令片段,cmdp 会很顺手。

它不试图替代 shell,也不试图替代 Makefile、justfile 或复杂任务系统。它更像一个交互式入口:把那些“经常用、略复杂、需要参数、最好先预览”的命令组织起来。

对我来说,它最大的价值不是省下几次敲键盘,而是减少上下文切换:不用翻历史记录,不用打开 README 找命令,不用在脑子里拼接一长串 flag。

只要打开 TUI,选命令,填参数,看预览,执行。

安装

cmdp - GitHub Releases

找到对应的架构,下载。

提供 RPMDEB、松散文件。

END