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:
Benedikt Peetz 2024-05-04 20:05:05 +02:00
parent 88f323d030
commit 7fdc752490
3 changed files with 95 additions and 18 deletions

View File

@ -179,7 +179,6 @@ pub async fn handle<U: TrinitrixUi>(
}
Raw::send_input_unprocessed { input } => {
let key = Key::from_str(input.as_str())?;
// let cross_input: Event = key.try_into()?;
match app.status.state() {
State::Insert | State::Command => {

View File

@ -2,6 +2,7 @@ mod app;
mod cli;
mod ui;
use anyhow::Context;
use clap::Parser;
use crate::{
@ -18,13 +19,13 @@ async fn main() -> anyhow::Result<()> {
match command {
Command::Start {} => {
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>
app.run(None, args.plugin_path).await?;
}
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>
app.run(None, args.plugin_path).await?;

View File

@ -1,51 +1,128 @@
use anyhow::Result;
use cli_log::info;
use std::io::{self, Stdout, Write};
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 crate::app::status::Status;
use crate::app::status::{State, Status};
use super::ui_trait::TrinitrixUi;
pub struct Repl {
current_written_buffer: String,
current_input: String,
enter_new_line: bool,
stdout: Stdout,
}
impl Repl {
pub fn new() -> Self {
println!("Welcome to the Trinitrix repl! You can now enter trinitry commands.");
print!("{}", Self::prompt(&Status::new()));
pub fn new() -> Result<Self> {
enable_raw_mode().context("Failed to enable raw mode")?;
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(),
enter_new_line: false,
}
stdout,
})
}
pub fn prompt(status: &Status) -> String {
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 {
async fn update(&mut self, status: &Status) -> Result<()> {
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.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(())
}
fn input(&mut self, input: Key) {
debug!("Input received at repl: {}", input);
if let Some(value) = input.value() {
if let KeyValue::Char(ch) = value {
self.current_input.push(*ch);
} else if let KeyValue::Enter = value {
self.enter_new_line = true;
match value {
KeyValue::Backspace => {
self.current_written_buffer.pop();
}
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 {
info!("User wrote: '{}'", input.to_string_repr());