From b08278807ee51e279c07dd6b7955713455a4c654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Sun, 13 Sep 2020 20:04:16 +0900 Subject: [PATCH] Add 'A', 'I' commands. --- helix-core/src/commands.rs | 78 +++++++++++++++++++++++++++++++++++ helix-core/src/transaction.rs | 8 ++++ helix-term/src/keymap.rs | 8 ++++ 3 files changed, 94 insertions(+) diff --git a/helix-core/src/commands.rs b/helix-core/src/commands.rs index 836667a1c..914ca0fe1 100644 --- a/helix-core/src/commands.rs +++ b/helix-core/src/commands.rs @@ -60,8 +60,86 @@ pub fn append_mode(state: &mut State, _count: usize) { }) } +// TODO: I, A, o and O can share a lot of the primitives. + // I inserts at the start of each line with a selection +pub fn prepend_to_line(state: &mut State, _count: usize) { + state.mode = Mode::Insert; + + // calculate line numbers for each selection range + let mut lines = state + .selection + .ranges() + .iter() + .map(|range| state.doc.char_to_line(range.head)) + .collect::>(); + + lines.sort(); + lines.dedup(); + + let positions: Vec<_> = lines + .into_iter() + .map(|index| { + // adjust all positions to the end of the line. + let line_start = state.doc.line_to_char(index); + line_start + }) + .collect(); + + let selection = Selection::new( + positions + .iter() + .copied() + .map(|pos| Range::new(pos, pos)) + .collect(), + 0, + ); + + let transaction = Transaction::new(state).with_selection(selection); + + transaction.apply(state); + // TODO: need to store into history if successful +} + // A inserts at the end of each line with a selection +pub fn append_to_line(state: &mut State, _count: usize) { + state.mode = Mode::Insert; + + // calculate line numbers for each selection range + let mut lines = state + .selection + .ranges() + .iter() + .map(|range| state.doc.char_to_line(range.head)) + .collect::>(); + + lines.sort(); + lines.dedup(); + + let positions: Vec<_> = lines + .into_iter() + .map(|index| { + // adjust all positions to the end of the line. + let line = state.doc.line(index); + let line_start = state.doc.line_to_char(index); + line_start + line.len_chars() - 1 + }) + .collect(); + + let selection = Selection::new( + positions + .iter() + .copied() + .map(|pos| Range::new(pos, pos)) + .collect(), + 0, + ); + + let transaction = Transaction::new(state).with_selection(selection); + + transaction.apply(state); + // TODO: need to store into history if successful +} // o inserts a new line after each line with a selection pub fn open_below(state: &mut State, _count: usize) { diff --git a/helix-core/src/transaction.rs b/helix-core/src/transaction.rs index 3d03de193..12ed523e4 100644 --- a/helix-core/src/transaction.rs +++ b/helix-core/src/transaction.rs @@ -322,6 +322,14 @@ pub struct Transaction { } impl Transaction { + /// Create a new, empty transaction. + pub fn new(state: &mut State) -> Self { + Self { + changes: ChangeSet::new(&state.doc), + selection: None, + } + } + /// Returns true if applied successfully. pub fn apply(&self, state: &mut State) -> bool { // apply changes to the document diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index 325157617..5611e1042 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -103,10 +103,18 @@ pub fn default() -> Keymap { code: KeyCode::Char('i'), modifiers: Modifiers::NONE } => commands::insert_mode as Command, + Key { + code: KeyCode::Char('I'), + modifiers: Modifiers::SHIFT, + } => commands::prepend_to_line as Command, Key { code: KeyCode::Char('a'), modifiers: Modifiers::NONE } => commands::append_mode as Command, + Key { + code: KeyCode::Char('A'), + modifiers: Modifiers::SHIFT, + } => commands::append_to_line as Command, Key { code: KeyCode::Char('o'), modifiers: Modifiers::NONE