Skip to content

Commit

Permalink
unfucking the cli: used raw mode to extrapolate events properly
Browse files Browse the repository at this point in the history
  • Loading branch information
Iamdavidonuh committed Oct 3, 2024
1 parent 7279f78 commit 92d3233
Showing 1 changed file with 117 additions and 36 deletions.
153 changes: 117 additions & 36 deletions ahnlich/cli/src/term.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,39 @@
use crossterm::event::{
poll, KeyboardEnhancementFlags, PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags,
};

use crossterm::{
cursor,
event::{self, Event, KeyCode, KeyEvent},
execute, queue,
style::{Color, Print, SetForegroundColor, Stylize},
terminal::{disable_raw_mode, enable_raw_mode},
ExecutableCommand,
};
use std::io::{self, stdout, Write};
use std::io::{self, stdout, Stdout, Write};

use crate::connect::AgentPool;

const RESERVED_WORDS: [&str; 3] = ["ping", "infoserver", "createpredindex"];

#[derive(Debug)]
enum SpecialEntry {
Enter,
Up,
Down,
Break,
Left,
Right,
}

#[derive(Debug)]
enum Entry {
Char(char),
Special(SpecialEntry),
Other(KeyCode),
None,
}

pub struct Term {
client_pool: AgentPool,
}
Expand All @@ -18,23 +43,20 @@ impl Term {
Self { client_pool }
}

pub(crate) fn read_line(&self) -> io::Result<String> {
let mut line = String::new();
while let Event::Key(KeyEvent { code, .. }) = event::read()? {
match code {
KeyCode::Enter => {
break;
}
KeyCode::Char(c) => {
line.push(c);
}
KeyCode::Esc => {
break;
}
_ => {}
}
pub(crate) fn read_char(&self) -> io::Result<Entry> {
if let Event::Key(KeyEvent { code, .. }) = event::read()? {
Ok(match code {
KeyCode::Enter => Entry::Special(SpecialEntry::Enter),
KeyCode::Char(c) => Entry::Char(c),
KeyCode::Left => Entry::Special(SpecialEntry::Left),
KeyCode::Up => Entry::Special(SpecialEntry::Up),
KeyCode::Down => Entry::Special(SpecialEntry::Down),
KeyCode::Right => Entry::Special(SpecialEntry::Right),
_ => Entry::Other(code),
})
} else {
Ok(Entry::None)
}
Ok(line)
}
pub fn welcome_message(&self) -> io::Result<()> {
let mut stdout = stdout();
Expand All @@ -48,50 +70,109 @@ impl Term {
Ok(())
}

pub(crate) fn ahnlich_prompt(&self) -> io::Result<()> {
let mut stdout = stdout();
pub(crate) fn ahnlich_prompt(&self, stdout: &mut Stdout) -> io::Result<()> {
stdout.execute(SetForegroundColor(Color::White))?;
stdout.execute(Print(">>> "))?;
stdout.execute(SetForegroundColor(Color::White))?;

stdout.flush()?;
//stdout.flush()?;
Ok(())
}

pub(crate) fn print_query(&self, query: &str) -> io::Result<()> {
self.ahnlich_prompt()?;
let output = String::from_iter(query.split(' ').map(|ex| {
if RESERVED_WORDS.contains(&(ex.to_lowercase().as_str())) {
format!("{} ", ex.magenta())
} else {
format!("{} ", ex.white())
}
}));
// pub(crate) fn print_query(&self, query: &str) -> io::Result<()> {
// self.ahnlich_prompt()?;
// let output = String::from_iter(query.split(' ').map(|ex| {
// if RESERVED_WORDS.contains(&(ex.to_lowercase().as_str())) {
// format!("{} ", ex.magenta())
// } else {
// format!("{} ", ex.white())
// }
// }));

println!("{output}");
// println!("{output}");

Ok(())
// Ok(())
// }

fn read_line(&self, stdout: &mut Stdout) -> io::Result<String> {
let (start_pos_col, _) = cursor::position()?;
let mut output = String::new();

loop {
let char = self.read_char()?;
let (current_pos_col, _) = cursor::position()?;
match char {
Entry::Char(c) => {
output.push(c);
stdout.execute(Print(c))?;
stdout.flush()?;
}
Entry::Special(special) => match special {
SpecialEntry::Up | SpecialEntry::Down => {
continue;
}
SpecialEntry::Enter | SpecialEntry::Break => {
queue!(stdout, Print("\n"), cursor::MoveToColumn(0))?;
stdout.flush()?;
break;
}
SpecialEntry::Left => {
if start_pos_col < current_pos_col {
stdout.execute(cursor::MoveLeft(1))?;
}
}
SpecialEntry::Right => {
if start_pos_col + output.len() as u16 > current_pos_col {
stdout.execute(cursor::MoveRight(1))?;
}
}
},
Entry::Other(_) | Entry::None => {
continue;
}
}
}
Ok(output)
}

pub async fn run(&self) -> io::Result<()> {
enable_raw_mode()?;
let mut stdout = stdout();
stdout.execute(cursor::EnableBlinking)?;
stdout.execute(cursor::SetCursorStyle::BlinkingBar)?;

loop {
self.ahnlich_prompt()?;
let input = self.read_line()?;
self.ahnlich_prompt(&mut stdout)?;
let input = self.read_line(&mut stdout)?;
match input.as_str() {
"quit" | "exit()" => break,
command => {
self.print_query(command)?;
let response = self.client_pool.parse_queries(command).await;

match response {
Ok(success) => {
println!("{}", success.join("\n\n"))
for msg in success {
queue!(
stdout,
Print(format!("{}\n", msg)),
cursor::MoveToColumn(0)
)?;
}
stdout.flush()?;
}
Err(err) => {
queue!(
stdout,
Print(format!("{}\n", err.red())),
cursor::MoveToColumn(0)
)?;
stdout.flush()?;
}
Err(err) => println!("{}", err.red()),
}
}
};
}
disable_raw_mode()?;
Ok(())
}
}

0 comments on commit 92d3233

Please sign in to comment.