use super::*;
fn inner_input(
state: &mut Ed<'_>,
mut input: Vec<String>,
index: usize,
) -> Result<()> {
let buffer = state.history.current_mut()?;
let mut tail = buffer.split_off(index);
for line in input.drain(..) {
buffer.push(Line::new(line, '\0'))
}
buffer.append(&mut tail);
Ok(())
}
enum InlineSide {
Before,
After,
}
fn inner_inline_input(
state: &mut Ed<'_>,
mut input: Vec<String>,
line: usize,
side: InlineSide,
) -> Result<()> {
let buffer = state.history.current_mut()?;
let mut tail = buffer.split_off(line);
let indexed_line = buffer.split_off(line - 1);
if input.len() == 0 { return Err(EdError::NoOp); }
let mut input_iter = input.drain(..);
match side {
InlineSide::Before => {
let mut joined_line = input_iter.next_back().unwrap();
joined_line.pop(); joined_line.push_str(&indexed_line[0].text[..]);
for line in input_iter {
buffer.push(Line::new(line, '\0'));
}
buffer.push(Line::new(joined_line, '\0'));
},
InlineSide::After => {
let mut joined_line = (&indexed_line[0].text[..]).to_owned();
joined_line.pop(); joined_line.push_str(&input_iter.next().unwrap());
buffer.push(Line::new(joined_line, '\0'));
for line in input_iter {
buffer.push(Line::new(line, '\0'));
}
},
}
buffer.append(&mut tail);
state.clipboard = (&*indexed_line).into();
Ok(())
}
pub fn input(
state: &mut Ed<'_>,
ui: &mut dyn UI,
pflags: &mut PrintingFlags,
selection: Option<Sel<'_>>,
command: char,
flags: &str,
) -> Result<()> {
let sel = interpret_selection(&state, selection, state.selection)?;
let mut flags = parse_flags(flags, "pnl")?;
pflags.p = flags.remove(&'p').unwrap();
pflags.n = flags.remove(&'n').unwrap();
pflags.l = flags.remove(&'l').unwrap();
let buffer = state.history.current();
match command {
'a' => buffer.verify_index(sel.1)?,
'i' => buffer.verify_index(sel.0.saturating_sub(1))?,
'A' => buffer.verify_line(sel.1)?,
'I' => buffer.verify_line(sel.0)?,
_ => { panic!("Unreachable code reached"); }
}
let input = ui.get_input(
state,
'.',
#[cfg(feature = "initial_input_data")]
None,
)?;
state.selection = if !input.is_empty() {
let index = match command {
'a' | 'A' => sel.1,
'i' => sel.0.saturating_sub(1),
'I' => sel.0,
_ => unreachable!(),
};
let start = index + 1; let end = start + input.len() - 1; match command {
'A' => {
inner_inline_input(state, input, index, InlineSide::After)?;
(start - 1, end - 1)
},
'I' => {
inner_inline_input(state, input, index, InlineSide::Before)?;
(start - 1,end - 1)
},
'a' | 'i' => {
inner_input(state, input, index)?;
(start, end)
},
_ => { panic!("Unreachable code reached"); }
}
}
else {
state.selection
};
Ok(())
}