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 } => {
|
||||
let key = Key::from_str(input.as_str())?;
|
||||
// let cross_input: Event = key.try_into()?;
|
||||
|
||||
match app.status.state() {
|
||||
State::Insert | State::Command => {
|
||||
|
|
|
@ -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?;
|
||||
|
|
|
@ -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());
|
||||
|
|
Reference in New Issue