mirror of
				https://github.com/rm-dr/daisy
				synced 2025-11-04 00:42:39 -08:00 
			
		
		
		
	Added cursor to promptbuffer
This commit is contained in:
		
							
								
								
									
										59
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										59
									
								
								src/main.rs
									
									
									
									
									
								
							@@ -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> {
 | 
			
		||||
	let mut stdout = stdout().into_raw_mode().unwrap();
 | 
			
		||||
@@ -108,17 +70,10 @@ fn main() -> Result<(), std::io::Error> {
 | 
			
		||||
	//write!(stdout, "{:?}", size).unwrap();
 | 
			
		||||
 | 
			
		||||
	let mut pb: PromptBuffer = PromptBuffer::new(64);
 | 
			
		||||
	let mut last_len: usize = 0;
 | 
			
		||||
 | 
			
		||||
	'outer: loop {
 | 
			
		||||
 | 
			
		||||
		let s = parser::substitute(&pb.get_contents());
 | 
			
		||||
		draw_line(
 | 
			
		||||
			&mut stdout, &s,
 | 
			
		||||
			if s.chars().count() >= last_len
 | 
			
		||||
			{ 0 } else {last_len - s.chars().count()}
 | 
			
		||||
		)?;
 | 
			
		||||
		last_len = s.chars().count();
 | 
			
		||||
		pb.write_prompt(&mut stdout)?;
 | 
			
		||||
 | 
			
		||||
		let stdin = stdin();
 | 
			
		||||
		for c in stdin.keys() {
 | 
			
		||||
@@ -175,8 +130,8 @@ fn main() -> Result<(), std::io::Error> {
 | 
			
		||||
				match c.unwrap() {
 | 
			
		||||
					Key::Backspace => { pb.backspace(); },
 | 
			
		||||
					Key::Delete => { pb.delete(); },
 | 
			
		||||
					Key::Left => {},
 | 
			
		||||
					Key::Right => {},
 | 
			
		||||
					Key::Left => { pb.cursor_left(); },
 | 
			
		||||
					Key::Right => { pb.cursor_right(); },
 | 
			
		||||
					Key::Up => { pb.hist_up(); },
 | 
			
		||||
					Key::Down => { pb.hist_down(); },
 | 
			
		||||
					
 | 
			
		||||
@@ -186,13 +141,7 @@ fn main() -> Result<(), std::io::Error> {
 | 
			
		||||
				};
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			let s = parser::substitute(&pb.get_contents());
 | 
			
		||||
			draw_line(
 | 
			
		||||
				&mut stdout, &s,
 | 
			
		||||
				if s.chars().count() >= last_len
 | 
			
		||||
				{ 0 } else {last_len - s.chars().count()}
 | 
			
		||||
			)?;
 | 
			
		||||
			last_len = s.chars().count();
 | 
			
		||||
			pb.write_prompt(&mut stdout)?;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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() }
 | 
			
		||||
	let mut new_s = s.clone();
 | 
			
		||||
 | 
			
		||||
@@ -156,6 +159,11 @@ pub fn substitute(s: &String) -> String{
 | 
			
		||||
	let (subs, _) = find_subs(tokens);
 | 
			
		||||
 | 
			
		||||
	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(
 | 
			
		||||
			r.0.pos..r.0.pos+r.0.len,
 | 
			
		||||
			&r.1[..]
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,10 @@
 | 
			
		||||
use std::collections::VecDeque;
 | 
			
		||||
use std::io::Write;
 | 
			
		||||
use termion::raw::RawTerminal;
 | 
			
		||||
use termion::color;
 | 
			
		||||
use termion::style;
 | 
			
		||||
 | 
			
		||||
use crate::parser::substitute;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
@@ -14,7 +20,8 @@ pub struct PromptBuffer {
 | 
			
		||||
 | 
			
		||||
	buffer: String,
 | 
			
		||||
	buffer_changed: bool,
 | 
			
		||||
	//cursor: usize // Counts from back of buffer
 | 
			
		||||
	cursor: usize,
 | 
			
		||||
	last_print_len: usize
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl PromptBuffer {
 | 
			
		||||
@@ -24,12 +31,49 @@ impl PromptBuffer {
 | 
			
		||||
			hist_maxlen: maxlen,
 | 
			
		||||
			hist_cursor: 0,
 | 
			
		||||
			buffer: String::with_capacity(64),
 | 
			
		||||
			buffer_changed: false
 | 
			
		||||
			//cursor: 0,
 | 
			
		||||
			buffer_changed: false,
 | 
			
		||||
			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
 | 
			
		||||
	pub fn get_contents(&self) -> &String {&self.buffer}
 | 
			
		||||
 | 
			
		||||
@@ -49,19 +93,60 @@ impl PromptBuffer {
 | 
			
		||||
 | 
			
		||||
	// Buffer manipulation
 | 
			
		||||
	pub fn add_char(&mut self, c: char) {
 | 
			
		||||
		self.buffer.push(c);
 | 
			
		||||
		self.buffer_changed = true;
 | 
			
		||||
	}
 | 
			
		||||
	pub fn backspace(&mut self) {
 | 
			
		||||
		if self.buffer.len() != 0 {
 | 
			
		||||
			self.buffer_changed = true;
 | 
			
		||||
			self.buffer.pop();
 | 
			
		||||
 | 
			
		||||
		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 delete(&mut self) {
 | 
			
		||||
		self.backspace();
 | 
			
		||||
	pub fn backspace(&mut self) {
 | 
			
		||||
		if self.buffer.len() == 0 { return }
 | 
			
		||||
		self.buffer_changed = true;
 | 
			
		||||
		let l = self.buffer.chars().count();
 | 
			
		||||
 | 
			
		||||
		if self.cursor == 0 {
 | 
			
		||||
			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) {
 | 
			
		||||
		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
 | 
			
		||||
	pub fn hist_up(&mut self) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user