use std::collections::HashMap;
pub mod error_consts;
mod cmd;
pub mod ui;
pub mod buffer;
use ui::UI;
use buffer::Buffer;
pub struct EdState<'a> {
pub selection: (usize, usize),
pub buffer: &'a dyn Buffer,
pub path: &'a str,
}
struct Substitution {
pattern: String,
substitute: String,
global: bool,
p: bool,
n: bool,
l: bool,
}
pub struct Ed <'a, B: Buffer> {
selection: (usize, usize),
buffer: &'a mut B,
path: String,
prev_s: Option<Substitution>,
dont_snapshot: bool,
cmd_prefix: Option<char>,
n: bool,
l: bool,
macros: HashMap<String, String>,
print_errors: bool,
error: Option<&'static str>,
}
impl <'a, B: Buffer> Ed <'a, B> {
pub fn new(
buffer: &'a mut B,
path: String,
macros: HashMap<String, String>,
n: bool,
l: bool,
) -> Result<Self, &'static str> {
if ! path.is_empty() {
buffer.read_from(&path, None, false)?;
}
let selection = (1,0); let tmp = Self {
print_errors: true,
error: None,
prev_s: None,
cmd_prefix: Some(':'),
selection,
dont_snapshot: false,
buffer,
path,
n,
l,
macros,
};
Ok(tmp)
}
pub fn run_command(
&mut self,
ui: &mut dyn UI,
command: &str,
) -> Result<bool, &'static str> {
match cmd::run(self, ui, command) {
Err(e) => {
self.error = Some(e);
Err(e)
},
x => x,
}
}
pub fn run_macro(
&mut self,
ui: &mut dyn UI,
) -> Result<(), &'static str> {
loop {
let cmd = match ui.get_command( self.see_state(), self.cmd_prefix ) {
Err(e) => { self.error = Some(e); return Err(e) },
Ok(x) => x,
};
if self.run_command(ui, &cmd)? {
break;
}
}
Ok(())
}
pub fn run(
&mut self,
ui: &mut dyn UI,
) -> Result<(), &'static str> {
loop {
match self.run_macro(ui) {
Ok(()) => break,
Err(e) => {
if self.print_errors {
ui.print_message(e)?;
}
else {
ui.print_message("?\n")?;
}
},
}
}
Ok(())
}
pub fn see_state(&self) -> EdState {
EdState{
selection: self.selection,
path: &self.path,
buffer: self.buffer,
}
}
}