feat(ui/repl): Get the development repl into a useful shape
This repl is not really meant for user, as it's quite features striped. Its main goal is to enable a faster debugging turnabout time.
This commit is contained in:
parent
88f323d030
commit
7fdc752490
|
@ -179,7 +179,6 @@ pub async fn handle<U: TrinitrixUi>(
|
||||||
}
|
}
|
||||||
Raw::send_input_unprocessed { input } => {
|
Raw::send_input_unprocessed { input } => {
|
||||||
let key = Key::from_str(input.as_str())?;
|
let key = Key::from_str(input.as_str())?;
|
||||||
// let cross_input: Event = key.try_into()?;
|
|
||||||
|
|
||||||
match app.status.state() {
|
match app.status.state() {
|
||||||
State::Insert | State::Command => {
|
State::Insert | State::Command => {
|
||||||
|
|
|
@ -2,6 +2,7 @@ mod app;
|
||||||
mod cli;
|
mod cli;
|
||||||
mod ui;
|
mod ui;
|
||||||
|
|
||||||
|
use anyhow::Context;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -18,13 +19,13 @@ async fn main() -> anyhow::Result<()> {
|
||||||
match command {
|
match command {
|
||||||
Command::Start {} => {
|
Command::Start {} => {
|
||||||
todo!("The full ui is not yet finished");
|
todo!("The full ui is not yet finished");
|
||||||
let mut app = app::App::new(Repl::new())?;
|
let mut app = app::App::new(Repl::new()?)?;
|
||||||
|
|
||||||
// NOTE(@soispha): The `None` here is temporary <2024-05-03>
|
// NOTE(@soispha): The `None` here is temporary <2024-05-03>
|
||||||
app.run(None, args.plugin_path).await?;
|
app.run(None, args.plugin_path).await?;
|
||||||
}
|
}
|
||||||
Command::Repl {} => {
|
Command::Repl {} => {
|
||||||
let mut app = app::App::new(Repl::new())?;
|
let mut app = app::App::new(Repl::new().context("Failed to setup repl")?)?;
|
||||||
|
|
||||||
// NOTE(@soispha): The `None` here is temporary <2024-05-03>
|
// NOTE(@soispha): The `None` here is temporary <2024-05-03>
|
||||||
app.run(None, args.plugin_path).await?;
|
app.run(None, args.plugin_path).await?;
|
||||||
|
|
|
@ -1,51 +1,128 @@
|
||||||
use anyhow::Result;
|
use std::io::{self, Stdout, Write};
|
||||||
use cli_log::info;
|
|
||||||
|
use anyhow::{Context, Result};
|
||||||
|
use cli_log::{debug, info};
|
||||||
|
use crossterm::{
|
||||||
|
execute,
|
||||||
|
terminal::{disable_raw_mode, enable_raw_mode, EnableLineWrap},
|
||||||
|
};
|
||||||
use keymaps::key_repr::{Key, KeyValue};
|
use keymaps::key_repr::{Key, KeyValue};
|
||||||
|
|
||||||
use crate::app::status::Status;
|
use crate::app::status::{State, Status};
|
||||||
|
|
||||||
use super::ui_trait::TrinitrixUi;
|
use super::ui_trait::TrinitrixUi;
|
||||||
|
|
||||||
pub struct Repl {
|
pub struct Repl {
|
||||||
|
current_written_buffer: String,
|
||||||
current_input: String,
|
current_input: String,
|
||||||
enter_new_line: bool,
|
enter_new_line: bool,
|
||||||
|
stdout: Stdout,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Repl {
|
impl Repl {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Result<Self> {
|
||||||
println!("Welcome to the Trinitrix repl! You can now enter trinitry commands.");
|
enable_raw_mode().context("Failed to enable raw mode")?;
|
||||||
print!("{}", Self::prompt(&Status::new()));
|
let mut stdout = io::stdout();
|
||||||
|
|
||||||
Repl {
|
write!(
|
||||||
|
stdout,
|
||||||
|
"Welcome to the Trinitrix repl! You can now enter trinitry commands."
|
||||||
|
)?;
|
||||||
|
write!(stdout, "\n\r{}", Self::prompt(&Status::new()))?;
|
||||||
|
stdout.flush()?;
|
||||||
|
|
||||||
|
Ok(Repl {
|
||||||
|
current_written_buffer: String::new(),
|
||||||
current_input: String::new(),
|
current_input: String::new(),
|
||||||
enter_new_line: false,
|
enter_new_line: false,
|
||||||
}
|
stdout,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
pub fn prompt(status: &Status) -> String {
|
pub fn prompt(status: &Status) -> String {
|
||||||
format!("{}> ", status.state())
|
format!("{}> ", status.state())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Drop for Repl {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
disable_raw_mode().expect("Must work in drop");
|
||||||
|
execute!(io::stdout(), EnableLineWrap).expect("Must also work");
|
||||||
|
|
||||||
|
writeln!(self.stdout, "\n\rBye!").expect("Must also work");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl TrinitrixUi for Repl {
|
impl TrinitrixUi for Repl {
|
||||||
async fn update(&mut self, status: &Status) -> Result<()> {
|
async fn update(&mut self, status: &Status) -> Result<()> {
|
||||||
if self.enter_new_line {
|
if self.enter_new_line {
|
||||||
info!("Got '{}' from user in repl.", self.current_input);
|
info!("Got '{}' from user in repl.", self.current_written_buffer);
|
||||||
|
|
||||||
|
if status.state() == &State::Command {
|
||||||
|
write!(
|
||||||
|
self.stdout,
|
||||||
|
"\n\rEvaluating: '{}' ..",
|
||||||
|
self.current_written_buffer
|
||||||
|
)?;
|
||||||
|
} else {
|
||||||
|
write!(
|
||||||
|
self.stdout,
|
||||||
|
"\n\rCan't insert anything in the repl besides in command mode!",
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
self.enter_new_line = false;
|
self.enter_new_line = false;
|
||||||
self.current_input = String::new();
|
self.current_written_buffer.clear();
|
||||||
|
|
||||||
print!("{}", Self::prompt(status));
|
write!(self.stdout, "\n\r{}", Self::prompt(status))?;
|
||||||
|
} else {
|
||||||
|
write!(
|
||||||
|
self.stdout,
|
||||||
|
"\r{}{}{}",
|
||||||
|
Self::prompt(status),
|
||||||
|
self.current_written_buffer,
|
||||||
|
self.current_input
|
||||||
|
)?;
|
||||||
|
|
||||||
|
self.current_written_buffer += self.current_input.as_str();
|
||||||
|
self.current_input.clear();
|
||||||
}
|
}
|
||||||
|
self.stdout.flush()?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn input(&mut self, input: Key) {
|
fn input(&mut self, input: Key) {
|
||||||
|
debug!("Input received at repl: {}", input);
|
||||||
|
|
||||||
if let Some(value) = input.value() {
|
if let Some(value) = input.value() {
|
||||||
if let KeyValue::Char(ch) = value {
|
match value {
|
||||||
self.current_input.push(*ch);
|
KeyValue::Backspace => {
|
||||||
} else if let KeyValue::Enter = value {
|
self.current_written_buffer.pop();
|
||||||
self.enter_new_line = true;
|
}
|
||||||
|
KeyValue::Enter => self.enter_new_line = true,
|
||||||
|
KeyValue::Left => todo!(),
|
||||||
|
KeyValue::Right => todo!(),
|
||||||
|
KeyValue::Up => todo!(),
|
||||||
|
KeyValue::Down => todo!(),
|
||||||
|
KeyValue::Home => todo!(),
|
||||||
|
KeyValue::End => todo!(),
|
||||||
|
KeyValue::PageUp => todo!(),
|
||||||
|
KeyValue::PageDown => todo!(),
|
||||||
|
KeyValue::Tab => todo!(),
|
||||||
|
KeyValue::BackTab => todo!(),
|
||||||
|
KeyValue::Delete => todo!(),
|
||||||
|
KeyValue::Insert => todo!(),
|
||||||
|
KeyValue::F(_) => todo!(),
|
||||||
|
KeyValue::Char(ch) => self.current_input.push(*ch),
|
||||||
|
KeyValue::Null => todo!(),
|
||||||
|
KeyValue::Esc => todo!(),
|
||||||
|
KeyValue::CapsLock => todo!(),
|
||||||
|
KeyValue::ScrollLock => todo!(),
|
||||||
|
KeyValue::NumLock => todo!(),
|
||||||
|
KeyValue::PrintScreen => todo!(),
|
||||||
|
KeyValue::Pause => todo!(),
|
||||||
|
KeyValue::Menu => todo!(),
|
||||||
|
KeyValue::KeypadBegin => todo!(),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
info!("User wrote: '{}'", input.to_string_repr());
|
info!("User wrote: '{}'", input.to_string_repr());
|
||||||
|
|
Reference in New Issue