use super::*;
fn inner_change(
state: &mut Ed<'_>,
full_command: &str,
mut input: Vec<String>,
selection: (usize, usize),
) -> Result<()> {
let buffer = state.history.current_mut(full_command.into());
let mut tail = buffer.split_off(selection.1);
state.clipboard = buffer.split_off(selection.0 - 1)[..].into();
for line in input.drain(..) {
buffer.push(Line::new(line).map_err(InternalError::InvalidLineText)?);
}
buffer.append(&mut tail);
Ok(())
}
pub fn change(
state: &mut Ed<'_>,
ui: &mut dyn UI,
pflags: &mut PrintingFlags,
full_command: &str,
selection: Option<Sel<'_>>,
command: char,
flags: &str,
) -> Result<()> {
let sel = interpret_selection(&state, selection, state.selection)?;
let buffer = state.history.current();
buffer.verify_selection(sel)?;
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();
#[allow(unused_variables)]
let initial_input_data: Option<Vec<String>> = if command == 'C' {
#[cfg(feature = "initial_input_data")]
{
Some(buffer[sel.0 - 1 .. sel.1].iter()
.map(|s| (&s.text[..]).to_owned())
.collect()
)
}
#[cfg(not(feature = "initial_input_data"))]
{
return Err(EdError::CommandUndefined(command));
}
} else {
None
};
let input = ui.get_input(
state,
'.',
#[cfg(feature = "initial_input_data")]
initial_input_data,
)?;
let inputlen = input.len();
if inputlen == 0 && sel.0 == 1 && sel.1 == buffer.len() {
if pflags.p || pflags.n || pflags.l {
return Err(EdError::PrintAfterWipe);
}
}
inner_change(state, full_command, input, sel)?;
let buffer = state.history.current();
state.selection = {
(1.max(
sel.0.min(buffer.len())
),
(sel.0 + inputlen.saturating_sub(1)).min(buffer.len())
)
};
Ok(())
}