3 个不稳定版本

新版本 0.4.0 2024年8月15日
0.3.1 2024年6月11日
0.3.0 2024年6月10日

240GUI

Download history 260/week @ 2024-06-08 25/week @ 2024-06-15 79/week @ 2024-08-10

79 每月下载量

MIT/ApacheGPL-3.0-or-later

300KB
8K SLoC

radicle-tui

Screenshot

radicle-tui 提供了各种终端用户界面,用于与 Radicle 代码库交互。它还暴露了构建应用框架。

目录

  1. 入门
  2. 应用框架
  3. 路线图
  4. 贡献
  5. 联系方式
  6. 许可证

入门

此软件包提供了一个名为 rad-tui 的二进制文件,其中包含所有用户界面。可以通过适当的命令运行特定界面,例如 rad-tui patch select 显示补丁选择器。

界面设计为模块化,并与现有的 Radicle CLI 良好集成。目前,二进制文件旨在由 rad 调用,它将收集和处理其输出,例如

rad patch show

将显示补丁选择器并传递所选补丁的 ID。

注意: Radicle CLI 的集成尚未完成。请参阅 使用 部分了解如何使用 rad-tui

安装

要求

  • LinuxUnix 类操作系统。
  • Git 2.34 或更高版本
  • OpenSSH 9.1 或更高版本,并带有 ssh-agent

从源代码

注意: 需要 Rust 工具链。

您可以通过在此存储库内部运行以下命令从源代码安装二进制文件

cargo install --path . --force --locked

或直接从我们的种子节点

cargo install --force --locked --git https://seed.radicle.xyz/z39mP9rQAaGmERfUMPULfPUi473tY.git

这将安装 rad-tui。所有可用的命令都可以通过运行 rad-tui --help 显示。

Nix

存储库中有一个 flake.nix 文件。这意味着对于开发,只需使用 direnv 并具有以下 .envrc 文件即可

# .envrc
use flake

在NixOS中使用二进制文件时,您可以在flake.nix中添加以下之一到inputs集合中

inputs = {
    # Replace <Tag> with the specific tag to build
    radicle-tui = {
        url = "git+https://seed.radicle.xyz/z3gqcJUoA1n9HaHKufZs5FCSGazv5.git?tag=<Tag>";
    }
}
inputs = {
    # Replace <Commit SHA> with the specific commit to build
    rad-tui = {
        url = "git+https://seed.radicle.xyz/z3gqcJUoA1n9HaHKufZs5FCSGazv5.git?rev=<Commit SHA>";
    }
}

然后在您的home.nix中可以添加

home.packages.inputs.radicle-tui.packages.{system}.default

使用

不久,rad-tui将集成到heartwood中。在此之前,您可以使用提供的rad代理脚本。它被视为rad的即插即用替代品,可用于测试和原型制作。它应该反映当前行为,例如,如果已集成rad-tui,则

# show an interface that let's you select a patch
./rad.sh patch show
# show an interface that let's you select a patch and an operation
./rad.sh patch --tui

这两个命令都将调用rad-tui,处理其输出并相应地调用rad

接口

选择一个补丁、一个问题或一个通知以及一个操作

rad-tui <patch | issue | inbox> select

与上面相同

rad-tui <patch | issue | inbox> select --mode operation

仅选择一个补丁、一个问题或一个通知并返回其ID

rad-tui <patch | issue | inbox> select --mode id

输出

所有接口都在stderr上返回一个共同的JSON对象,该对象反映了用户所做的选择,例如

{ "operation": "show", "ids": ["546443226b300484a97a2b2d7c7000af6e8169ba"], args:[] }

应用框架

此包的库部分是一个框架,是所有radicle-tui二进制文件的基础。该框架建立在ratatui之上,主要遵循Flux应用程序模式。它借鉴了tui-realmcursive的一些想法。并发模型主要受rust-chat-server的启发。

注意:现有的核心功能被认为是稳定的,但API可能随时会更改。虽然新功能(如配置、用户定义的快捷键、主题等)将很快添加。

该框架附带一个小部件库,它提供低级小部件(如列表、文本字段等),以及高级应用程序小部件(如窗口、页面和各种其他容器)。

注意:小部件库正在积极开发中,并且仍然缺少大多数低级小部件。这些将由radicle-tui二进制文件根据需要添加。

设计

该框架是根据几个设计目标构建的

  • async:状态更新和I/O应该是异步的,不应阻塞UI
  • declarative:开发者应更多地考虑What而不是How
  • widget library:自定义小部件应易于构建;预制的组件应具有默认的用户交互和渲染

框架的核心是StoreFrontend以及一个消息传递系统,允许它们相互通信。Store处理集中式应用程序状态并向Frontend发送更新,而Frontend处理用户交互并向Store发送消息,从而相应地更新状态。

在此之上,构建了一个可扩展的小部件库。小部件由实现View特性和包裹在其中的Widget定义。一个View处理用户交互,每当应用程序状态改变时都会更新自己并频繁渲染。一个Widget添加了额外的属性和事件、更新和渲染回调支持。属性定义了小部件的数据、配置等。它们由框架更新,通过on_update回调构建属性。使用on_event回调在组件接收到事件时发出应用程序消息。

主要思路是构建能够处理其特定事件的控件,并通过 on_update 回调更新属性。通过设置 on_event 回调添加自定义逻辑。例如,Table 控件已经可以处理项目选择;项目通过 on_update 回调设置,并通过 on_event 回调发出应用程序消息。

示例

use anyhow::Result;

use termion::event::Key;

use ratatui::text::Text;

use radicle_tui as tui;

use tui::store;
use tui::ui::widget::text::{TextArea, TextAreaProps};
use tui::ui::widget::ToWidget;
use tui::{BoxedAny, Channel, Exit};

/// Centralized application state.
#[derive(Clone, Debug)]
struct State {
    hello: String,
}

/// All messages known by the application.
enum Message {
    Quit,
}

/// Implementation of the app-state trait. It's updated whenever a message was received.
/// Applications quit whenever an `Exit` is returned by the `update` function. The `Exit`
/// type also provides and optional return value. 
impl store::State<()> for State {
    type Message = Message;

    fn update(&mut self, message: Self::Message) -> Option<tui::Exit<()>> {
        match message {
            Message::Quit => Some(Exit { value: None }),
        }
    }
}

/// 1. Initializes the communication channel between frontend and state store
/// 2. Initializes the application state
/// 3. Builds a textarea widget which renders a welcome message and quits the 
///    application when (q) is pressed
/// 4. Runs the TUI application
#[tokio::main]
pub async fn main() -> Result<()> {
    let channel = Channel::default();
    let sender = channel.tx.clone();
    let state = State {
        hello: "Hey there, press (q) to quit...".to_string(),
    };

    let textarea = TextArea::default()
        .to_widget(sender.clone())
        .on_event(|key, _, _| match key {
            Key::Char('q') => Some(Message::Quit),
            _ => None,
        })
        .on_update(|state: &State| {
            TextAreaProps::default()
                .text(&Text::raw(state.hello.clone()))
                .to_boxed_any()
                .into()
        });

    tui::run(channel, state, textarea).await?;

    Ok(())
}

路线图

项目路线图主要取决于 Radicle 团队的需求。如果您缺少某些内容或有任何改进建议,请随时 联系我们

现在

  • 选择界面中的补丁和问题预览
  • 基本的 radicle-cli 集成

接下来

  • 支持多选列表和树形控件
  • 从文件中读取配置
  • 支持用户自定义快捷键
  • 补丁评审

稍后

  • 简化 CLI 集成,为 rad 命令提供配置和标志(例如 rad patch edit --tui
  • 从 JSON 输入读取 COBs
  • 添加对自定义主题的支持

贡献

贡献使开源社区成为一个如此令人惊叹的学习、灵感和创造的地方。您所做的任何贡献都将受到高度赞赏。

如果您有任何改进建议,请克隆存储库并打开补丁。您也可以简单地打开一个带有“增强”标签的问题。

联系方式

请在 Zulip 上联系我们。

许可证

radicle-tui 在 MIT 许可证和 Apache 许可证(版本 2.0)的条款下分发。

有关详细信息,请参阅 LICENSE-APACHELICENSE-MIT

依赖项

~148MB
~3.5M SLoC