4 个版本 (稳定版)
2.0.0 | 2024 年 4 月 12 日 |
---|---|
1.1.0 | 2024 年 3 月 22 日 |
1.0.0 | 2024 年 3 月 12 日 |
0.1.0 | 2020 年 12 月 10 日 |
在 配置 中排名第 84
71KB
1.5K SLoC
rmuxinator
这是什么?
该项目旨在成为 tmuxinator 的继任者,它允许用户定义 tmux 项目配置文件(例如,打开两个窗口,每个窗口分成三个面板,并在每个面板中运行一系列命令)。它是用 Rust 编写的,将更加可靠(尽可能进行类型检查)且安装更简单。这对我来说也是一个学习更多关于 Rust、其生态系统以及跨平台编译和分发二进制文件的好机会。
简单来说;我该如何使用它?
- 安装 tmux (>= 2.8),rust 和 cargo
Cargo
- 安装:
cargo install rmuxinator
- 运行:
rmuxinator start samples/Example.toml
源代码
cargo构建
- 构建:
cargo build && ./target/debug/rmuxinator start samples/Example.toml
- 运行:
./target/debug/rmuxinator start samples/Example.toml
cargo运行
- 运行:
cargo run start samples/Example.toml
文档
项目配置
项目使用 toml 格式定义。
例如
attached = true
layout = "main-horizontal"
name = "example"
pane_name_user_option = "custom_pane_title"
start_directory = "/home/peter/projects/vim"
tmux_options = "-f /tmp/tmux.work.conf -L work-socket"
[[hooks]]
command = "run-shell \"tmux display-message 'Hi from pane-focus-in hook!'\""
name = "pane-focus-in"
[[windows]]
layout = "tiled"
name = "one"
start_directory = "/home/peter/projects/sample-project"
[[windows.panes]]
commands = ["echo pane-one"]
name = "Work"
[[windows.panes]]
commands = ["echo pane-two"]
name = "Music"
start_directory = "/home/peter/projects/rmuxinator/src"
[[windows.panes]]
commands = ["echo pane-three"]
name = "RSS"
[[windows.panes]]
commands = ["echo hi one", "echo intermediate one", "echo bye one"]
[[windows]]
name = "two"
start_directory = "/home/peter/projects/sample-project"
[[windows.panes]]
commands = ["echo pane-one"]
[[windows.panes]]
commands = ["echo pane-two"]
start_directory = "/home/peter/projects/rmuxinator/src"
[[windows.panes]]
commands = ["echo pane-three"]
[[windows.panes]]
commands = ["echo hi one", "echo intermediate one", "echo bye one"]
配置选项
以下将说明可选属性。
项目
name
(字符串)windows
(数组;请参阅相关条目)
可选
attached
(布尔值;默认为true
;是否连接到新创建的 tmux 会话)hooks
(数组;请参阅相关条目)layout
(字符串;预设的 tmux 布局:"even-horizontal","even-vertical","main-horizontal","main-vertical","tiled")pane_name_user_option
(字符串;必须在 .tmux.conf 中有匹配项(例如,set -g pane-border-format "#{@custom_pane_title}"
)start_directory
(字符串)tmux_options
(字符串;传递给 tmux 的 CLI 标志)
钩子
command
(字符串;必须使用 tmux 的run_shell
;参阅 tmux 文档)name
(字符串;必须匹配现有的 tmux 钩子(例如after-select-pane
);参阅 tmux 文档)
窗口
panes
(数组;参阅专用条目)
可选
layout
(字符串;预设的 tmux 布局:"even-horizontal","even-vertical","main-horizontal","main-vertical","tiled")name
(字符串)start_directory
(字符串)
窗格
commands
(字符串数组)
可选
name
(字符串)start_directory
(字符串)
命令
调试
打印使用项目配置文件路径启动和配置 tmux 会话的 tmux 命令:rmuxinator debug samples/Example.toml
开始
使用项目配置文件路径启动 tmux 会话:rmuxinator start samples/Example.toml
作为库使用
rmuxinator 也可以被其他程序作为库使用。
有两种实现方式
Config::new_from_config_path
此选项接受一个 rmuxinator 配置文件路径,这是 rmuxinator 二进制文件的工作方式。这是本项目的二进制入口点的工作方式。
示例
let config = rmuxinator::Config::new_from_config_path(&String::from("/home/pi/foo.toml")).map_err(|error| format!("Problem parsing config file: {}", error))?;
rmuxinator::run_start(config).map_err(|error| format!("Rmuxinator error: {}", error));
Config 构造函数
此选项允许调用者创建一个 rmuxinator Config
结构,并将其传递给 run_start
函数。
pi-wall-utils 项目(也由 ethagnawl 维护)就是这样做的,可以用作参考。
示例
let rmuxinator_config = rmuxinator::Config {
attached: true,
hooks: vec![],
layout: None,
name: String::from("rmuxinator-library-example"),
windows: vec![
rmuxinator::Window {
layout: None,
name: None,
panes: vec![rmuxinator::Pane {
commands: vec![
String::from("echo 'hello!'"),
],
name: None,
start_directory: None,
}],
start_directory: None,
}
];
};
rmuxinator::run_start(rmuxinator_config).map_err(|error| format!("Rmuxinator error: {}", error))
已知问题和解决方案
自定义 Tmux 配置
如果您通过 tmux_options 提供自定义的 tmux 配置文件,您可能需要在某些/所有更改生效之前重新启动您的 tmux 服务器(tmux kill-server
)。例如,对 base-index
和 pane-base-index
的更改已知需要重新启动才能按预期检测和使用。
可能可以通过解决这个问题,但这需要更多的思考。一种强硬的选项是让这个库明确地终止并重新启动 tmux 服务器,但这可能会在其他 tmux 会话正在使用时产生意想不到的后果。
状态
该项目目前是一个概念验证,我将在找到时间时复制 tmuxinator 功能并添加额外的改进。目前,它能够
- 解析 TOML 项目配置文件
- 启动命名的 tmux 会话
- 设置项目窗口的默认布局
- 设置默认工作目录
- 创建窗口
- 设置窗口的 cwd
- 设置窗口布局
- 创建窗格
- 设置窗格的 cwd
- 使用“用户选项”设置窗格标题(需要 >= tmux 3.0a 和相关的窗格边框格式配置选项)
- 运行窗格命令
- 连接可选的 tmux 事件钩子/回调
- 检测/使用 tmux 服务器基础索引和窗格基础索引值
- 通过 tmux_options 配置字段接受自定义 tmux CLI 选项
仍 TODO
- 考虑构建并执行单个脚本(类似于 tmuxinator)而不是多次外壳调用
- 支持自定义布局?
- 将库分解为组件文件(Config,CliArgs 等)
- 我们需要自定义钩子,比如 tmuxinator 使用的 pre_window,project_start 等?我希望利用 tmux 的钩子,但映射不是 1:1,用户可能需要求助于像钩子移除自己这样的技巧来防止重复事件。
- CliArgs.project_name 应该反映它是一个文件路径
- 看起来格式不需要消耗值,所以引用(总是?)不是必要的
- 使用功能检测有条件地应用/排除某些功能(用户选项)
- 集成测试,验证复合/推导值(例如 start_directory)
- 集成测试,验证对 tmux 的调用?
- 处理外壳失败 --
tmux kill-server
返回静默失败 - 是否可以将所有命令都移动到结构体中并提前计算?这可能需要为 Config 类型编写自定义的 Serde 反序列化器。
- 在附加时选择窗口(这能否由现有的钩子处理?)
- 如果存在会话,则附加而不是创建会话
- 在磁盘上搜索项目配置文件(XDG_CONFIG?)而不是解析配置(我不确定这是否必要)
- 其他 CLI 命令?(停止会话,创建/编辑/删除项目)
- 尽可能在调用 format! 时使用命名参数
- (完全)实现 Config 结构体的默认/派生功能
平台
以下是 rmuxinator 已知的可以工作的平台
- x86_64 GNU/Linux
- x86_64 GNU/Linux(Windows 子shell)
- armv6l GNU/Linux(RPi Zero;我能够从 Debian x86_64 => armv6l 成功交叉编译使用 raspberrypi/tools 仓库中提供的 arm-linux-gnueabihf 链接器。Debian 软件包不起作用;我能够成功编译,但程序在执行时立即崩溃。)
资源
- https://github.com/raspberrypi/tools
- https://old.reddit.com/r/rust/comments/9io0z8/run_crosscompiled_code_on_rpi_0/
- https://medium.com/@wizofe/cross-compiling-rust-for-arm-e-g-raspberry-pi-using-any-os-11711ebfc52b
- https://devel.tech/tips/n/tMuXz2lj/the-power-of-tmux-hooks/
- https://cli.rust-lang.net.cn/book/tutorial/testing.html
依赖项
~4.5–6.5MB
~110K SLoC