diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 43edfb9..eb8b404 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -162,26 +162,44 @@ pub fn parse( pub fn substitute( - s: &String, // The string to subsitute + s: &String, // The string to substitute c: usize // Location of the cursor right now -) -> String{ - if s == "" { return s.clone() } +) -> ( + usize, // Location of cursor in substituted string + String // String with substitutions +) { + if s == "" { return (c, s.clone()) } let mut new_s = s.clone(); + let l = s.chars().count(); let tokens = tokenize(s); let (subs, _) = find_subs(tokens); + let mut new_c = l - c; for r in subs.iter() { - if { // Don't subsitute if our cursor is inside the substitution + // find_subs gives substitutions in reverse order. + + if { // Don't substitute if our cursor is inside the substitution c >= r.0.pos && c < r.0.pos+r.0.len } { continue; } + if c < r.0.pos { + let ct = r.1.chars().count(); + if ct >= r.0.len { + if new_c >= ct - r.0.len { + new_c += ct - r.0.len + } + } else { + new_c -= r.0.len - ct + } + } + new_s.replace_range( r.0.pos..r.0.pos+r.0.len, &r.1[..] ) } - return new_s; + return (new_c, new_s); } \ No newline at end of file diff --git a/src/promptbuffer.rs b/src/promptbuffer.rs index c38bef5..511e000 100644 --- a/src/promptbuffer.rs +++ b/src/promptbuffer.rs @@ -39,11 +39,12 @@ impl PromptBuffer { pub fn write_prompt(&mut self, stdout: &mut RawTerminal) -> Result<(), std::io::Error> { - let i = self.buffer.chars().count(); - let i = if i == 0 {0} else {i - self.cursor}; + let l = self.buffer.chars().count(); + let i = if l == 0 {0} else {l - self.cursor}; // Draw prettyprinted expression - let s = substitute(&self.get_contents(), i); + let (display_cursor, s) = substitute(&self.get_contents(), i); + write!( stdout, "\r{}{}==>{}{} {}", style::Bold, @@ -52,7 +53,7 @@ impl PromptBuffer { style::Reset, s )?; - + // If this string is shorter, clear the remaining old one. if s.chars().count() < self.last_print_len { write!( @@ -61,12 +62,13 @@ impl PromptBuffer { termion::cursor::Left((self.last_print_len - s.chars().count()) as u16) )?; } - + + // Move cursor to correct position - if self.cursor != 0 { + if display_cursor != 0 { write!( stdout, "{}", - termion::cursor::Left(self.cursor as u16) + termion::cursor::Left(display_cursor as u16) )?; stdout.flush()?; }