add_ed/cmd/editing_commands/
input.rs1use super::*;
2
3fn inner_input(
4 state: &mut Ed<'_>,
5 full_command: &str,
6 mut input: Vec<String>,
7 index: usize,
8) -> Result<()> {
9 let buffer = state.history.current_mut(full_command.into());
10 let mut tail = buffer.split_off(index);
11 for line in input.drain(..) {
12 buffer.push(Line::new(line).map_err(InternalError::InvalidLineText)?);
13 }
14 buffer.append(&mut tail);
15 Ok(())
16}
17enum InlineSide {
18 Before,
19 After,
20}
21fn inner_inline_input(
22 state: &mut Ed<'_>,
23 full_command: &str,
24 mut input: Vec<String>,
25 line: usize,
26 side: InlineSide,
27) -> Result<()> {
28 let buffer = state.history.current_mut(full_command.into());
29 let mut tail = buffer.split_off(line);
30 let indexed_line = buffer.split_off(line - 1);
31 if input.len() == 0 { return Err(EdError::NoOp); }
33 let mut input_iter = input.drain(..);
34 match side {
37 InlineSide::Before => {
38 let mut joined_line = input_iter.next_back().unwrap();
40 joined_line.pop(); joined_line.push_str(&indexed_line[0].text[..]);
42 for line in input_iter {
43 buffer.push(Line::new(line).map_err(InternalError::InvalidLineText)?);
44 }
45 buffer.push(Line::new(joined_line)
49 .map_err(InternalError::InvalidLineText)?
50 );
51 },
52 InlineSide::After => {
53 let mut joined_line = (&indexed_line[0].text[..]).to_owned();
55 joined_line.pop(); joined_line.push_str(&input_iter.next().unwrap());
57 buffer.push(Line::new(joined_line)
60 .map_err(InternalError::InvalidLineText)?
61 );
62 for line in input_iter {
63 buffer.push(Line::new(line).map_err(InternalError::InvalidLineText)?);
64 }
65 },
66 }
67 buffer.append(&mut tail);
68 state.clipboard = (&*indexed_line).into();
69 Ok(())
70}
71pub fn input(
72 state: &mut Ed<'_>,
73 ui: &mut dyn UI,
74 pflags: &mut PrintingFlags,
75 full_command: &str,
76 selection: Option<Sel<'_>>,
77 command: char,
78 flags: &str,
79) -> Result<()> {
80 let mut flags = parse_flags(flags, "pnl")?;
81 pflags.p = flags.remove(&'p').unwrap();
82 pflags.n = flags.remove(&'n').unwrap();
83 pflags.l = flags.remove(&'l').unwrap();
84
85 let buffer = state.history.current();
86 let index = match command {
87 'a' | 'A' => {
88 let i = interpret_index_from_selection(&state, selection, state.selection, true)?;
89 if command == 'a' { buffer.verify_index(i)? } else { buffer.verify_line(i)? }
90 i
91 },
92 'i' | 'I' => {
95 let mut i = interpret_index_from_selection(&state, selection, state.selection, false)?;
96 if command == 'i' {
97 i = i.saturating_sub(1);
98 buffer.verify_index(i)?;
99 }
100 else { buffer.verify_line(i)? }
101 i
102 },
103 _ => ed_unreachable!()?,
104 };
105 let input = ui.get_input(
108 state,
109 '.',
110 #[cfg(feature = "initial_input_data")]
111 None,
112 )?;
113 state.selection = if !input.is_empty() {
117 let start = index + 1; let end = start + input.len() - 1; match command {
122 'A' => {
123 inner_inline_input(state, full_command, input, index, InlineSide::After)?;
124 (start - 1, end - 1)
126 },
127 'I' => {
128 inner_inline_input(state, full_command, input, index, InlineSide::Before)?;
129 (start - 1,end - 1)
130 },
131 'a' | 'i' => {
132 inner_input(state, full_command, input, index)?;
133 (start, end)
134 },
135 _ => ed_unreachable!()?,
136 }
137 }
138 else {
140 state.selection
141 };
142 Ok(())
143}