diff --git a/src/edit.rs b/src/edit.rs
index d4056c3..42b3e62 100644
--- a/src/edit.rs
+++ b/src/edit.rs
@@ -1,4 +1,5 @@
use crate::{
+ history::History,
input::{self, ControlCharacter, Escape},
log::*,
output,
@@ -206,7 +207,7 @@ impl Editor {
/// reads one command from the editor. This function blocks until the user has entered an
/// entire command.
- pub fn read_command(&mut self) -> Result> {
+ pub fn read_command(&mut self, _history: &mut History) -> Result > {
use input::Event::*;
loop {
diff --git a/src/history.rs b/src/history.rs
new file mode 100644
index 0000000..d7ce8bd
--- /dev/null
+++ b/src/history.rs
@@ -0,0 +1,7 @@
+pub struct History {}
+
+impl History {
+ pub fn new() -> Self {
+ Self {}
+ }
+}
diff --git a/src/input.rs b/src/input.rs
index ae8efb9..01705a1 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -239,6 +239,8 @@ impl Reader {
let c = as_escape_character(&record).ok_or(InputError::BadEscapeSequence)?;
if let Some(escape) = self.escapes.step(c) {
return Ok(escape);
+ } else {
+ return Ok(Escape::Empty);
}
}
}
@@ -416,7 +418,7 @@ impl EscapeNode {
impl EscapeCursor {
fn step(&mut self, c: char) -> Option {
debug!("step: {c}");
- let child = self.target.child(c).unwrap();
+ let child = self.target.child(c)?;
match child.as_ref() {
EscapeNode::Terminal { v, .. } => {
self.reset();
diff --git a/src/interactive.rs b/src/interactive.rs
index dfd3b7e..c4760bd 100644
--- a/src/interactive.rs
+++ b/src/interactive.rs
@@ -1,5 +1,6 @@
use crate::{
edit,
+ history::History,
log::*,
output,
run::{self, Eval},
@@ -39,10 +40,12 @@ impl Session {
stderr: self.stderr.clone(),
state: &mut state,
};
+ let mut history = History::new();
+
info!("ยป shell session start --------");
loop {
self.editor.show_prompt()?;
- let text = match self.editor.read_command()? {
+ let text = match self.editor.read_command(&mut history)? {
Some(text) => text,
None => break,
};
diff --git a/src/main.rs b/src/main.rs
index e7a5c75..5c636a4 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -19,6 +19,8 @@ mod lex;
/// a real primitive line editor
mod edit;
+mod history;
+
/// logging configuration
mod log;
diff --git a/src/parse.rs b/src/parse.rs
index b6db748..52104e7 100644
--- a/src/parse.rs
+++ b/src/parse.rs
@@ -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
/// cursor to any node on the tree, the tree remains in memory. Once there are no cursors pointed
/// at the tree, it is dropped.
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub struct Cursor {
pub target: Rc,
root: Rc,
@@ -148,6 +148,7 @@ impl Cursor {
Ok(())
}
+ /// moves the cursor up to the root of the tree in place
pub fn up_to_root(&mut self) {
self.goto(Rc::clone(&self.root));
}
@@ -174,6 +175,22 @@ impl Cursor {
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) {
self.prev = self.target.id;
self.target = next;