pub mod messages;
#[macro_use]
pub mod error;
pub use error::{
Result,
EdError,
};
mod cmd;
pub mod ui;
use ui::{UI, UILock, ScriptedUI};
pub mod io;
use io::IO;
mod history;
pub use history::History;
pub mod macros;
use macros::{Macro, MacroGetter};
pub use buffer::iters::*;
mod buffer;
pub use buffer::{
LineText,
Line,
Buffer,
PubLine,
Clipboard,
};
pub struct Substitution {
pub pattern: String,
pub substitute: String,
pub global: bool,
pub p: bool,
pub n: bool,
pub l: bool,
}
pub struct Ed <'a> {
pub history: History<Buffer>,
pub clipboard: Clipboard,
pub selection: (usize, usize),
pub io: &'a mut dyn IO,
pub file: String,
pub prev_shell_command: String,
pub prev_s: Option<Substitution>,
pub cmd_prefix: Option<char>,
pub n: bool,
pub l: bool,
pub print_errors: bool,
pub error: Option<EdError>,
pub macro_getter: &'a dyn MacroGetter,
pub recursion_limit: usize,
}
impl <'a, > Ed <'a> {
pub fn new(
io: &'a mut dyn IO,
macro_getter: &'a dyn MacroGetter,
) -> Self {
let selection = (1,0);
Self {
selection,
history: History::new(),
prev_s: None,
prev_shell_command: String::new(),
file: String::new(),
clipboard: Clipboard::new(),
error: None,
print_errors: true,
n: false,
l: false,
cmd_prefix: Some(':'),
recursion_limit: 16,
io,
macro_getter,
}
}
pub fn run_command(
&mut self,
ui: &mut dyn UI,
command: &str,
) -> Result<bool> {
self.private_run_command(ui, command, 0)
}
fn private_run_command(
&mut self,
ui: &mut dyn UI,
command: &str,
recursion_depth: usize,
) -> Result<bool> {
match cmd::run(self, ui, command, recursion_depth) {
Err(e) => {
self.error = Some(e.clone());
Err(e)
},
x => x,
}
}
pub fn get_and_run_command(
&mut self,
ui: &mut dyn UI,
) -> Result<bool> {
self.private_get_and_run_command(ui, 0)
}
fn private_get_and_run_command(
&mut self,
ui: &mut dyn UI,
recursion_depth: usize,
) -> Result<bool> {
let mut clos = || {
let cmd = ui.get_command(self, self.cmd_prefix)?;
self.private_run_command(ui, &cmd, recursion_depth)
};
match clos() {
Err(e) => {
self.error = Some(e.clone());
Err(e)
},
x => x,
}
}
pub fn run_macro<
S: std::ops::Deref<Target = str>,
>(
&mut self,
ui: &mut dyn UI,
mac: &Macro,
arguments: &[S],
) -> Result<()> {
self.private_run_macro(ui, mac, arguments, 0)
}
fn private_run_macro<
S: std::ops::Deref<Target = str>,
>(
&mut self,
ui: &mut dyn UI,
mac: &Macro,
arguments: &[S],
recursion_depth: usize,
) -> Result<()> {
let to_run = macros::apply_arguments(mac, arguments)?;
let mut script_ui = ScriptedUI{
input: to_run.lines().map(|x| format!("{}\n",x)).collect(),
print_ui: Some(ui),
};
loop {
if self.private_get_and_run_command(&mut script_ui, recursion_depth)? {
break;
}
}
Ok(())
}
pub fn run(
&mut self,
ui: &mut dyn UI,
) -> Result<()> {
loop {
match self.get_and_run_command(ui) {
Ok(true) => break,
Ok(false) => (),
Err(e) => {
if self.print_errors {
ui.print_message(&e.to_string())?;
}
else {
ui.print_message("?\n")?;
}
},
}
}
Ok(())
}
}