3 个不稳定版本
新版本 0.4.0 | 2024年8月15日 |
---|---|
0.3.1 | 2024年6月11日 |
0.3.0 | 2024年6月10日 |
240 在 GUI
79 每月下载量
300KB
8K SLoC
radicle-tui
radicle-tui
提供了各种终端用户界面,用于与 Radicle 代码库交互。它还暴露了构建应用框架。
目录
入门
此软件包提供了一个名为 rad-tui
的二进制文件,其中包含所有用户界面。可以通过适当的命令运行特定界面,例如 rad-tui patch select
显示补丁选择器。
界面设计为模块化,并与现有的 Radicle CLI 良好集成。目前,二进制文件旨在由 rad
调用,它将收集和处理其输出,例如
rad patch show
将显示补丁选择器并传递所选补丁的 ID。
注意: Radicle CLI 的集成尚未完成。请参阅 使用 部分了解如何使用
rad-tui
。
安装
要求
- Linux 或 Unix 类操作系统。
- 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-realm和cursive的一些想法。并发模型主要受rust-chat-server的启发。
注意:现有的核心功能被认为是稳定的,但API可能随时会更改。虽然新功能(如配置、用户定义的快捷键、主题等)将很快添加。
该框架附带一个小部件库,它提供低级小部件(如列表、文本字段等),以及高级应用程序小部件(如窗口、页面和各种其他容器)。
注意:小部件库正在积极开发中,并且仍然缺少大多数低级小部件。这些将由
radicle-tui
二进制文件根据需要添加。
设计
该框架是根据几个设计目标构建的
- async:状态更新和I/O应该是异步的,不应阻塞UI
- declarative:开发者应更多地考虑What而不是How
- widget library:自定义小部件应易于构建;预制的组件应具有默认的用户交互和渲染
框架的核心是Store
、Frontend
以及一个消息传递系统,允许它们相互通信。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-APACHE 和 LICENSE-MIT。
依赖项
~148MB
~3.5M SLoC