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

MIT 许可协议

71KB
1.5K SLoC

rmuxinator

Screenshot

这是什么?

该项目旨在成为 tmuxinator 的继任者,它允许用户定义 tmux 项目配置文件(例如,打开两个窗口,每个窗口分成三个面板,并在每个面板中运行一系列命令)。它是用 Rust 编写的,将更加可靠(尽可能进行类型检查)且安装更简单。这对我来说也是一个学习更多关于 Rust、其生态系统以及跨平台编译和分发二进制文件的好机会。

简单来说;我该如何使用它?

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-indexpane-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 软件包不起作用;我能够成功编译,但程序在执行时立即崩溃。)

资源

依赖项

~4.5–6.5MB
~110K SLoC