pressing escape no longer crashes the shell

main
Jordan Orelli 7 months ago
parent 5676c6ddcc
commit 731bd69477

@ -1,4 +1,5 @@
use crate::{ use crate::{
history::History,
input::{self, ControlCharacter, Escape}, input::{self, ControlCharacter, Escape},
log::*, log::*,
output, output,
@ -206,7 +207,7 @@ impl Editor {
/// reads one command from the editor. This function blocks until the user has entered an /// reads one command from the editor. This function blocks until the user has entered an
/// entire command. /// entire command.
pub fn read_command(&mut self) -> Result<Option<String>> { pub fn read_command(&mut self, _history: &mut History) -> Result<Option<String>> {
use input::Event::*; use input::Event::*;
loop { loop {

@ -0,0 +1,7 @@
pub struct History {}
impl History {
pub fn new() -> Self {
Self {}
}
}

@ -239,6 +239,8 @@ impl Reader {
let c = as_escape_character(&record).ok_or(InputError::BadEscapeSequence)?; let c = as_escape_character(&record).ok_or(InputError::BadEscapeSequence)?;
if let Some(escape) = self.escapes.step(c) { if let Some(escape) = self.escapes.step(c) {
return Ok(escape); return Ok(escape);
} else {
return Ok(Escape::Empty);
} }
} }
} }
@ -416,7 +418,7 @@ impl EscapeNode {
impl EscapeCursor { impl EscapeCursor {
fn step(&mut self, c: char) -> Option<Escape> { fn step(&mut self, c: char) -> Option<Escape> {
debug!("step: {c}"); debug!("step: {c}");
let child = self.target.child(c).unwrap(); let child = self.target.child(c)?;
match child.as_ref() { match child.as_ref() {
EscapeNode::Terminal { v, .. } => { EscapeNode::Terminal { v, .. } => {
self.reset(); self.reset();

@ -1,5 +1,6 @@
use crate::{ use crate::{
edit, edit,
history::History,
log::*, log::*,
output, output,
run::{self, Eval}, run::{self, Eval},
@ -39,10 +40,12 @@ impl Session {
stderr: self.stderr.clone(), stderr: self.stderr.clone(),
state: &mut state, state: &mut state,
}; };
let mut history = History::new();
info!("» shell session start --------"); info!("» shell session start --------");
loop { loop {
self.editor.show_prompt()?; self.editor.show_prompt()?;
let text = match self.editor.read_command()? { let text = match self.editor.read_command(&mut history)? {
Some(text) => text, Some(text) => text,
None => break, None => break,
}; };

@ -19,6 +19,8 @@ mod lex;
/// a real primitive line editor /// a real primitive line editor
mod edit; mod edit;
mod history;
/// logging configuration /// logging configuration
mod log; mod log;

@ -103,7 +103,7 @@ fn next_id() -> usize {
/// within a parse tree. The cursor helps with the ownership structure: so long as there is a /// within a parse tree. The cursor helps with the ownership structure: so long as there is a
/// cursor to any node on the tree, the tree remains in memory. Once there are no cursors pointed /// cursor to any node on the tree, the tree remains in memory. Once there are no cursors pointed
/// at the tree, it is dropped. /// at the tree, it is dropped.
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct Cursor { pub struct Cursor {
pub target: Rc<Node>, pub target: Rc<Node>,
root: Rc<Node>, root: Rc<Node>,
@ -148,6 +148,7 @@ impl Cursor {
Ok(()) Ok(())
} }
/// moves the cursor up to the root of the tree in place
pub fn up_to_root(&mut self) { pub fn up_to_root(&mut self) {
self.goto(Rc::clone(&self.root)); self.goto(Rc::clone(&self.root));
} }
@ -174,6 +175,22 @@ impl Cursor {
Rc::clone(&self.root) Rc::clone(&self.root)
} }
fn text_tree(&self) -> String {
let mut p = self.clone();
p.up_to_root();
let mut buf = String::new();
self.text_tree_helper(0, &mut buf);
buf
}
fn text_tree_helper(&self, depth: u32, mut buf: &mut String) {
let line = format!("{:?}\n", self.value());
*buf = buf.to_owned() + &line;
for child in self.iter_children() {
child.text_tree_helper(depth + 1, &mut buf);
}
}
fn goto(&mut self, next: Rc<Node>) { fn goto(&mut self, next: Rc<Node>) {
self.prev = self.target.id; self.prev = self.target.id;
self.target = next; self.target = next;

Loading…
Cancel
Save