diff --git a/src/edit.rs b/src/edit.rs
index 42b3e62..53e8629 100644
--- a/src/edit.rs
+++ b/src/edit.rs
@@ -207,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, _history: &mut History) -> Result> {
+ pub fn read_command(&mut self, history: &mut History) -> Result > {
use input::Event::*;
loop {
@@ -266,6 +266,7 @@ impl Editor {
match esc {
Left => self.back(1)?,
Right => self.forward(1)?,
+ Up => self.prev_history()?,
Home => self.seek_left()?,
End => self.seek_right()?,
esc => debug!(" Ignored escape: {esc:?}"),
@@ -422,4 +423,8 @@ impl Editor {
self.display.reset()?;
Ok(())
}
+
+ fn prev_history(&mut self) -> Result<()> {
+ Ok(())
+ }
}
diff --git a/src/error.rs b/src/error.rs
index 1e40b27..5c1d8f0 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -1,4 +1,7 @@
-use crate::{lex::Token, topo::Glyph};
+use crate::{
+ lex::Token,
+ topo::{Glyph, Position},
+};
use std::io;
use thiserror::Error;
use windows::Win32::Foundation::{GetLastError, BOOL};
@@ -36,21 +39,32 @@ pub enum LexError {
UnexpectedCharacterInGlob(Glyph),
#[error("unexpected eof")]
- UnexpectedEOF,
+ UnexpectedEOF(Position),
- #[error("not yet supported: {0}")]
- NotYetSupported(String),
+ #[error("not yet supported: {1}")]
+ NotYetSupported(Position, String),
}
impl LexError {
- pub fn not_yet(msg: &str) -> Self {
- LexError::NotYetSupported(msg.to_string())
+ pub fn not_yet(p: Position, msg: &str) -> Self {
+ LexError::NotYetSupported(p, msg.to_string())
+ }
+
+ fn position(&self) -> Position {
+ use LexError::*;
+ match self {
+ UnexpectedCharacter(g) => g.position,
+ UnexpectedCharacterInBareString(g) => g.position,
+ UnexpectedCharacterInGlob(g) => g.position,
+ UnexpectedEOF(p) => *p,
+ NotYetSupported(p, _) => *p,
+ }
}
}
#[derive(Debug, Error)]
pub enum ParseError {
- #[error("lex error")]
+ #[error("lex error at line {line}, column {col}", line=.0.position().line, col=.0.position().column)]
LexError(#[from] LexError),
#[error("Unexpected Token: {0:?}")]
diff --git a/src/history.rs b/src/history.rs
index d7ce8bd..21d28f2 100644
--- a/src/history.rs
+++ b/src/history.rs
@@ -1,7 +1,13 @@
-pub struct History {}
+pub struct History {
+ events: Vec,
+}
impl History {
pub fn new() -> Self {
- Self {}
+ Self { events: Vec::new() }
+ }
+
+ pub fn add>(&mut self, event: S) {
+ self.events.push(event.into());
}
}
diff --git a/src/lex.rs b/src/lex.rs
index 34877fc..45ef286 100644
--- a/src/lex.rs
+++ b/src/lex.rs
@@ -154,7 +154,7 @@ impl<'text> Tokenizer<'text> {
}
if progress.is_empty() {
- Err(LexError::UnexpectedEOF)
+ Err(LexError::UnexpectedEOF(self.source.next_position))
} else {
Ok(Token::Word(progress.into()))
}
@@ -175,22 +175,31 @@ impl<'text> Tokenizer<'text> {
}
if progress.is_empty() {
- Err(LexError::UnexpectedEOF)
+ Err(LexError::UnexpectedEOF(self.source.next_position))
} else {
Ok(Token::Glob(progress.into()))
}
}
fn lex_raw_string(&mut self, _progress: Vec) -> Result {
- Err(LexError::not_yet("raw strings not done yet"))
+ Err(LexError::not_yet(
+ self.source.next_position,
+ "raw strings not done yet",
+ ))
}
fn lex_interp_string(&mut self, _progress: Vec) -> Result {
- Err(LexError::not_yet("interpreted strings not done yet"))
+ Err(LexError::not_yet(
+ self.source.next_position,
+ "interpreted strings not done yet",
+ ))
}
fn lex_var(&mut self, _progress: Vec) -> Result {
- Err(LexError::not_yet("variables are not done yet"))
+ Err(LexError::not_yet(
+ self.source.next_position,
+ "variables are not done yet",
+ ))
}
}
diff --git a/src/topo.rs b/src/topo.rs
index a824998..fd9af1c 100644
--- a/src/topo.rs
+++ b/src/topo.rs
@@ -47,6 +47,12 @@ impl fmt::Debug for Position {
}
}
+impl fmt::Display for Position {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
+ (self as &dyn fmt::Debug).fmt(f)
+ }
+}
+
/// A Glyph represents a character occurring at some specific position in some input text.
#[derive(PartialEq, Clone)]
pub struct Glyph {
@@ -97,7 +103,7 @@ pub struct Glyphs<'text> {
source: Chars<'text>,
/// the position of the next character in the source text
- next_position: Position,
+ pub(crate) next_position: Position,
/// the number of bytes we've read from our input document so far
bytes_read: u64,
@@ -153,7 +159,8 @@ impl<'text> Glyphs<'text> {
/// takes the next character from our input text
pub fn pop(&mut self) -> Result {
- self.next().ok_or(LexError::UnexpectedEOF)
+ self.next()
+ .ok_or(LexError::UnexpectedEOF(self.next_position))
}
/// returns a reference to a character in our lookahead buffer at a given position. This allows