Added cursor to promptbuffer

pull/2/head
Mark 2023-03-27 22:13:14 -07:00
parent 56521cbbcd
commit bcb90b503d
Signed by: Mark
GPG Key ID: AD62BB059C2AAEE4
3 changed files with 109 additions and 67 deletions

View File

@ -60,44 +60,6 @@ fn draw_greeter(stdout: &mut RawTerminal<std::io::Stdout>) -> Result<(), std::io
} }
fn draw_line(
stdout: &mut RawTerminal<std::io::Stdout>,
s: &String,
clear_len: usize
) -> Result<(), std::io::Error> {
write!(
stdout, "\r{}{}==>{}{} {}",
style::Bold,
color::Fg(color::Blue),
color::Fg(color::Reset),
style::Reset,
s
)?;
// If this string is shorter, clear the remaining old one.
if clear_len != 0 {
write!(
stdout, "{}{}",
" ".repeat(clear_len as usize),
termion::cursor::Left(clear_len as u16)
)?;
}
stdout.flush()?;
return Ok(());
}
/*
#[cfg(debug_assertions)]
RawTerminal::suspend_raw_mode(&stdout)?;
#[cfg(debug_assertions)]
write!(stdout, "\n")?;
#[cfg(debug_assertions)]
RawTerminal::activate_raw_mode(&stdout)?;
*/
fn main() -> Result<(), std::io::Error> { fn main() -> Result<(), std::io::Error> {
let mut stdout = stdout().into_raw_mode().unwrap(); let mut stdout = stdout().into_raw_mode().unwrap();
@ -108,17 +70,10 @@ fn main() -> Result<(), std::io::Error> {
//write!(stdout, "{:?}", size).unwrap(); //write!(stdout, "{:?}", size).unwrap();
let mut pb: PromptBuffer = PromptBuffer::new(64); let mut pb: PromptBuffer = PromptBuffer::new(64);
let mut last_len: usize = 0;
'outer: loop { 'outer: loop {
let s = parser::substitute(&pb.get_contents()); pb.write_prompt(&mut stdout)?;
draw_line(
&mut stdout, &s,
if s.chars().count() >= last_len
{ 0 } else {last_len - s.chars().count()}
)?;
last_len = s.chars().count();
let stdin = stdin(); let stdin = stdin();
for c in stdin.keys() { for c in stdin.keys() {
@ -175,8 +130,8 @@ fn main() -> Result<(), std::io::Error> {
match c.unwrap() { match c.unwrap() {
Key::Backspace => { pb.backspace(); }, Key::Backspace => { pb.backspace(); },
Key::Delete => { pb.delete(); }, Key::Delete => { pb.delete(); },
Key::Left => {}, Key::Left => { pb.cursor_left(); },
Key::Right => {}, Key::Right => { pb.cursor_right(); },
Key::Up => { pb.hist_up(); }, Key::Up => { pb.hist_up(); },
Key::Down => { pb.hist_down(); }, Key::Down => { pb.hist_down(); },
@ -186,13 +141,7 @@ fn main() -> Result<(), std::io::Error> {
}; };
}; };
let s = parser::substitute(&pb.get_contents()); pb.write_prompt(&mut stdout)?;
draw_line(
&mut stdout, &s,
if s.chars().count() >= last_len
{ 0 } else {last_len - s.chars().count()}
)?;
last_len = s.chars().count();
} }
} }

View File

@ -148,7 +148,10 @@ pub fn parse(
} }
pub fn substitute(s: &String) -> String{ pub fn substitute(
s: &String, // The string to subsitute
c: usize // Location of the cursor right now
) -> String{
if s == "" { return s.clone() } if s == "" { return s.clone() }
let mut new_s = s.clone(); let mut new_s = s.clone();
@ -156,6 +159,11 @@ pub fn substitute(s: &String) -> String{
let (subs, _) = find_subs(tokens); let (subs, _) = find_subs(tokens);
for r in subs.iter() { for r in subs.iter() {
if { // Don't subsitute if our cursor is inside the substitution
c >= r.0.pos &&
c < r.0.pos+r.0.len
} { continue; }
new_s.replace_range( new_s.replace_range(
r.0.pos..r.0.pos+r.0.len, r.0.pos..r.0.pos+r.0.len,
&r.1[..] &r.1[..]

View File

@ -1,4 +1,10 @@
use std::collections::VecDeque; use std::collections::VecDeque;
use std::io::Write;
use termion::raw::RawTerminal;
use termion::color;
use termion::style;
use crate::parser::substitute;
#[derive(Debug)] #[derive(Debug)]
@ -14,7 +20,8 @@ pub struct PromptBuffer {
buffer: String, buffer: String,
buffer_changed: bool, buffer_changed: bool,
//cursor: usize // Counts from back of buffer cursor: usize,
last_print_len: usize
} }
impl PromptBuffer { impl PromptBuffer {
@ -24,12 +31,49 @@ impl PromptBuffer {
hist_maxlen: maxlen, hist_maxlen: maxlen,
hist_cursor: 0, hist_cursor: 0,
buffer: String::with_capacity(64), buffer: String::with_capacity(64),
buffer_changed: false buffer_changed: false,
//cursor: 0, cursor: 0,
last_print_len: 0,
}; };
} }
pub fn write_prompt(&mut self, stdout: &mut RawTerminal<std::io::Stdout>) -> Result<(), std::io::Error> {
// Draw prettyprinted expression
let s = substitute(&self.get_contents(), self.get_cursor_idx());
write!(
stdout, "\r{}{}==>{}{} {}",
style::Bold,
color::Fg(color::Blue),
color::Fg(color::Reset),
style::Reset,
s
)?;
// If this string is shorter, clear the remaining old one.
if s.chars().count() < self.last_print_len {
write!(
stdout, "{}{}",
" ".repeat(self.last_print_len - s.chars().count()),
termion::cursor::Left((self.last_print_len - s.chars().count()) as u16)
)?;
}
// Move cursor to correct position
if self.cursor != 0 {
write!(
stdout, "{}",
termion::cursor::Left(self.cursor as u16)
)?;
stdout.flush()?;
}
self.last_print_len = s.chars().count();
stdout.flush()?;
return Ok(());
}
// Prompt methods // Prompt methods
pub fn get_contents(&self) -> &String {&self.buffer} pub fn get_contents(&self) -> &String {&self.buffer}
@ -49,19 +93,60 @@ impl PromptBuffer {
// Buffer manipulation // Buffer manipulation
pub fn add_char(&mut self, c: char) { pub fn add_char(&mut self, c: char) {
self.buffer.push(c);
self.buffer_changed = true; self.buffer_changed = true;
if self.cursor == 0 {
self.buffer.push(c);
} else {
let l = self.buffer.chars().count();
let i = l - self.cursor;
self.buffer.insert(i, c);
}
} }
pub fn backspace(&mut self) { pub fn backspace(&mut self) {
if self.buffer.len() != 0 { if self.buffer.len() == 0 { return }
self.buffer_changed = true; self.buffer_changed = true;
let l = self.buffer.chars().count();
if self.cursor == 0 {
self.buffer.pop(); self.buffer.pop();
} else if self.cursor != l {
let i = l - self.cursor;
self.buffer.remove(i-1);
if self.cursor >= l {
self.cursor = l-1;
} }
} }
pub fn delete(&mut self) {
self.backspace();
} }
pub fn delete(&mut self) {
if self.cursor != 0 {
self.cursor -= 1;
self.backspace();
}
}
// Cursor manipulation
pub fn cursor_left(&mut self) {
let l = self.buffer.chars().count();
if self.cursor < l {
self.cursor += 1;
}
}
pub fn cursor_right(&mut self) {
if self.cursor > 0 {
self.cursor -= 1;
}
}
pub fn get_cursor(&self) -> usize { self.cursor }
pub fn get_cursor_idx(&self) -> usize {
let l = self.buffer.chars().count();
if l == 0 {0} else {l - self.cursor}
}
// History manipulation // History manipulation
pub fn hist_up(&mut self) { pub fn hist_up(&mut self) {