mirror of
https://seed.radicle.dev/rad:z39mP9rQAaGmERfUMPULfPUi473tY.git
synced 2026-10-18 19:10:36 +08:00
Improve README
This commit is contained in:
@@ -1,8 +1,16 @@
|
||||
# radicle-tui
|
||||
|
||||
_Radicle terminal user interfaces_
|
||||

|
||||
|
||||
## Installation
|
||||
`radicle-tui` provides various terminal user interfaces for interacting with the [Radicle](https://radicle.xyz) code forge and exposes the application framework they were built with.
|
||||
|
||||
## Binaries
|
||||
|
||||
This crate provides a single binary called `rad-tui`, which contains all user interfaces. Specific interfaces can be run by the appropriate command, e.g. `rad-tui patch select` shows a patch selector.
|
||||
|
||||
The interfaces are designed to be modular and to integrate well with the existing Radicle CLI. Right now, they are meant to be called from other programs that will collect and process their output.
|
||||
|
||||
### Installation
|
||||
|
||||
**Requirements**
|
||||
|
||||
@@ -10,87 +18,128 @@ _Radicle terminal user interfaces_
|
||||
- Git 2.34 or later
|
||||
- OpenSSH 9.1 or later with `ssh-agent`
|
||||
|
||||
### 📦 From source
|
||||
#### From source
|
||||
|
||||
> Requires the Rust toolchain.
|
||||
|
||||
You can install the binary from source, by running the following
|
||||
commands from inside this repository:
|
||||
|
||||
cargo install --path . --force --locked
|
||||
```
|
||||
cargo install --path . --force --locked
|
||||
```
|
||||
|
||||
Or directly from our seed node:
|
||||
|
||||
cargo install --force --locked --git https://seed.radicle.xyz/z39mP9rQAaGmERfUMPULfPUi473tY.git
|
||||
```
|
||||
cargo install --force --locked --git https://seed.radicle.xyz/z39mP9rQAaGmERfUMPULfPUi473tY.git
|
||||
```
|
||||
|
||||
This will install `rad-tui`. You can execute it by running `rad-tui`. All available commands can be shown by running `rad-tui --help`.
|
||||
|
||||
## Interfaces
|
||||
|
||||
The Radicle terminal interfaces are designed to be modular and to integrate well with the existing Radicle CLI. Right now, they are meant to be called from other programs that will collect and process their output.
|
||||
|
||||
### Usage
|
||||
|
||||
#### Patches
|
||||
|
||||
Select a patch and an operation:
|
||||
|
||||
$ rad-tui patch select
|
||||
{ "operation": "show", "ids": ["546443226b300484a97a2b2d7c7000af6e8169ba"], args:[] }
|
||||
|
||||
Select a patch, an issue or a notification and an operation:
|
||||
|
||||
```
|
||||
$ rad-tui <patch | issue | inbox> select
|
||||
```
|
||||
Same as above:
|
||||
|
||||
$ rad-tui patch select --mode operation
|
||||
{ "operation": "show", "ids": ["546443226b300484a97a2b2d7c7000af6e8169ba"], args:[] }
|
||||
```
|
||||
$ rad-tui <patch | issue | inbox> select --mode operation
|
||||
```
|
||||
|
||||
Select a patch only and return its id:
|
||||
Select a patch, an issue or a notification only and return its id:
|
||||
|
||||
$ rad-tui patch select --mode id
|
||||
{ "operation": "null", "ids": ["546443226b300484a97a2b2d7c7000af6e8169ba"], args:[] }
|
||||
```
|
||||
$ rad-tui <patch | issue | inbox> select --mode id
|
||||
```
|
||||
|
||||
#### Issues
|
||||
### Output
|
||||
|
||||
Select an issue and an operation:
|
||||
All interfaces return a JSON object that reflects the choices made by the user, e.g.:
|
||||
|
||||
$ rad-tui issue select
|
||||
{ "operation": "show", "ids": ["12f019e3f9f52d88b470a3d7fb922452ebaca39e"], args:[] }
|
||||
```
|
||||
{ "operation": "show", "ids": ["546443226b300484a97a2b2d7c7000af6e8169ba"], args:[] }
|
||||
```
|
||||
|
||||
## Framework
|
||||
|
||||
Same as above:
|
||||
The library portion of this crate is a framework that is the foundation for the interfaces mentioned above. The framework is built on top of [ratatui](https://ratatui.rs) and was inspired by the Flux application pattern. It took some ideas from [cursive](https://github.com/gyscos/cursive) and [rust-chat-server](https://github.com/Yengas/rust-chat-server).
|
||||
|
||||
$ rad-tui issue select --mode operation
|
||||
{ "operation": "show", "ids": ["12f019e3f9f52d88b470a3d7fb922452ebaca39e"], args:[] }
|
||||
### Example
|
||||
|
||||
```rust
|
||||
use anyhow::Result;
|
||||
use termion::event::Key;
|
||||
|
||||
Select an issue only and return its id:
|
||||
use radicle_tui as tui;
|
||||
|
||||
$ rad-tui issue select --mode id
|
||||
{ "operation": "null", "ids": ["12f019e3f9f52d88b470a3d7fb922452ebaca39e"], args:[] }
|
||||
use tui::store;
|
||||
use tui::ui::widget::text::{Paragraph, ParagraphProps};
|
||||
use tui::ui::widget::{Properties, Widget};
|
||||
use tui::{Channel, Exit};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct State {
|
||||
welcome: String,
|
||||
}
|
||||
|
||||
#### Inbox
|
||||
enum Message {
|
||||
Quit,
|
||||
ReverseWelcome,
|
||||
}
|
||||
|
||||
Select a notification and an operation:
|
||||
impl store::State<()> for State {
|
||||
type Message = Message;
|
||||
|
||||
$ rad-tui inbox select
|
||||
{ "operation": "show", "ids": ["1"], args:[] }
|
||||
fn update(&mut self, message: Self::Message) -> Option<tui::Exit<()>> {
|
||||
match message {
|
||||
Message::Quit => Some(Exit { value: None }),
|
||||
Message::ReverseWelcome => {
|
||||
self.welcome = self.welcome.chars().rev().collect::<String>();
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn tick(&self) {}
|
||||
}
|
||||
|
||||
Same as above:
|
||||
#[tokio::main]
|
||||
pub async fn main() -> Result<()> {
|
||||
let channel = Channel::default();
|
||||
let state = State {
|
||||
welcome: "Hello TUI".to_string(),
|
||||
};
|
||||
|
||||
$ rad-tui inbox select --mode operation
|
||||
{ "operation": "show", "ids": ["1"], args:[] }
|
||||
let welcome = Paragraph::new(&state, channel.tx.clone())
|
||||
.on_update(|state| {
|
||||
ParagraphProps::default()
|
||||
.text(&state.welcome.clone().into())
|
||||
.to_boxed()
|
||||
})
|
||||
.on_event(|paragraph, key| {
|
||||
paragraph
|
||||
.downcast_mut::<Paragraph<'_, State, Message>>()
|
||||
.and_then(|paragraph| match key {
|
||||
Key::Char('r') => paragraph.send(Message::ReverseWelcome).ok(),
|
||||
Key::Char('q') => paragraph.send(Message::Quit).ok(),
|
||||
_ => None,
|
||||
});
|
||||
})
|
||||
.to_boxed();
|
||||
|
||||
tui::run(channel, state, welcome).await?;
|
||||
|
||||
Select a notification only and return its id:
|
||||
|
||||
$ rad-tui inbox select --mode id
|
||||
{ "operation": "null", "ids": ["1"], args:[] }
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## License
|
||||
|
||||
Radicle is distributed under the terms of both the MIT license and the Apache License (Version 2.0).
|
||||
`radicle-tui` is distributed under the terms of both the MIT license and the Apache License (Version 2.0).
|
||||
|
||||
See [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT) for details.
|
||||
|
||||
+2
-1
@@ -95,7 +95,8 @@ impl<W: Write> ratatui::backend::Backend for TermionBackendExt<W> {
|
||||
pub fn setup(height: usize) -> anyhow::Result<Terminal<Backend>> {
|
||||
let stdout = io::stdout().into_raw_mode()?;
|
||||
let options = TerminalOptions {
|
||||
viewport: Viewport::Inline(height as u16),
|
||||
// viewport: Viewport::Inline(height as u16),
|
||||
viewport: Viewport::Fullscreen,
|
||||
};
|
||||
|
||||
Ok(Terminal::with_options(
|
||||
|
||||
Reference in New Issue
Block a user