From 9f37a6558adfd637236ad6d27080e1bd30c82b79 Mon Sep 17 00:00:00 2001 From: "NGnius (Graham)" Date: Thu, 10 Mar 2022 20:52:48 -0500 Subject: [PATCH] Fix backspacing in middle of line for REPL --- mps-interpreter/src/tokens/tokenizer.rs | 1 - src/repl.rs | 55 +++++++++++++++++++------ 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/mps-interpreter/src/tokens/tokenizer.rs b/mps-interpreter/src/tokens/tokenizer.rs index f79a3e6..5b6a73e 100644 --- a/mps-interpreter/src/tokens/tokenizer.rs +++ b/mps-interpreter/src/tokens/tokenizer.rs @@ -182,7 +182,6 @@ where } fn current_column(&self) -> usize { - println!("Current column: {}", self.column); self.column } diff --git a/src/repl.rs b/src/repl.rs index 6ec3da2..596ba72 100644 --- a/src/repl.rs +++ b/src/repl.rs @@ -168,21 +168,52 @@ fn read_loop(args: &CliArgs, state: &mut ReplState, mut execute: F) } }, Key::Backspace => { - if let Some(c) = state.statement_buf.pop() { - match c { - '\n' | '\r' => { - // another line, cannot backspace that far - state.statement_buf.push(c); - } - _ => { - state.current_line.pop(); - state.terminal.move_cursor_left(1).expect("Failed to write to terminal output"); - write!(state.terminal, " ").expect("Failed to write to terminal output"); - state.terminal.flush().expect("Failed to flush terminal output"); - state.terminal.move_cursor_left(1).expect("Failed to write to terminal output"); + if state.cursor_rightward_position == 0 { + if let Some(c) = state.statement_buf.pop() { + match c { + '\n' | '\r' => { + // another line, cannot backspace that far + state.statement_buf.push(c); + } + _ => { + state.current_line.pop(); + state.terminal.move_cursor_left(1).expect("Failed to write to terminal output"); + write!(state.terminal, " ").expect("Failed to write to terminal output"); + state.terminal.flush().expect("Failed to flush terminal output"); + state.terminal.move_cursor_left(1).expect("Failed to write to terminal output"); + } } } + } else { + if state.current_line.len() != state.cursor_rightward_position { + // if not at start of line + let removed_char = state.current_line.remove(state.current_line.len()-state.cursor_rightward_position-1); + state.statement_buf.remove(state.statement_buf.len()-state.cursor_rightward_position-1); + // re-sync unclosed syntax tracking + match removed_char { + '"' | '`' => { + if let Some(c) = state.in_literal { + if c == removed_char { + state.in_literal = None; + } + } + }, + '(' => if state.bracket_depth != 0 { state.bracket_depth -= 1 }, + ')' => state.bracket_depth += 1, + '{' => if state.curly_depth != 0 { state.curly_depth -= 1 }, + '}' => state.curly_depth += 1, + _ => {}, + } + // re-print end of line to remove character in middle + state.terminal.move_cursor_left(1).expect("Failed to write to terminal output"); + for i in state.current_line.len() - state.cursor_rightward_position .. state.current_line.len() { + write!(state.terminal, "{}", state.current_line[i]).expect("Failed to write to terminal output"); + } + write!(state.terminal, " ").expect("Failed to write to terminal output"); + state.terminal.move_cursor_left(state.cursor_rightward_position + 1).expect("Failed to write to terminal output"); + } } + }, Key::Enter => { state.terminal.write_line("").expect("Failed to write to terminal output");