on master help sign in
Add 'A', 'I' commands.
b082788Blaž Hrastnik
helix-core/src/commands.rs+78
@@ -60,8 +60,86 @@ pub fn append_mode(state: &mut State, _count: usize) {
60 })
60 })
61}
61}
62
62
63+// TODO: I, A, o and O can share a lot of the primitives.
64+
63// I inserts at the start of each line with a selection
65// I inserts at the start of each line with a selection
66+pub fn prepend_to_line(state: &mut State, _count: usize) {
67+ state.mode = Mode::Insert;
68+
69+ // calculate line numbers for each selection range
70+ let mut lines = state
71+ .selection
72+ .ranges()
73+ .iter()
74+ .map(|range| state.doc.char_to_line(range.head))
75+ .collect::<Vec<_>>();
76+
77+ lines.sort();
78+ lines.dedup();
79+
80+ let positions: Vec<_> = lines
81+ .into_iter()
82+ .map(|index| {
83+ // adjust all positions to the end of the line.
84+ let line_start = state.doc.line_to_char(index);
85+ line_start
86+ })
87+ .collect();
88+
89+ let selection = Selection::new(
90+ positions
91+ .iter()
92+ .copied()
93+ .map(|pos| Range::new(pos, pos))
94+ .collect(),
95+ 0,
96+ );
97+
98+ let transaction = Transaction::new(state).with_selection(selection);
99+
100+ transaction.apply(state);
101+ // TODO: need to store into history if successful
102+}
103+
64// A inserts at the end of each line with a selection
104// A inserts at the end of each line with a selection
105+pub fn append_to_line(state: &mut State, _count: usize) {
106+ state.mode = Mode::Insert;
107+
108+ // calculate line numbers for each selection range
109+ let mut lines = state
110+ .selection
111+ .ranges()
112+ .iter()
113+ .map(|range| state.doc.char_to_line(range.head))
114+ .collect::<Vec<_>>();
115+
116+ lines.sort();
117+ lines.dedup();
118+
119+ let positions: Vec<_> = lines
120+ .into_iter()
121+ .map(|index| {
122+ // adjust all positions to the end of the line.
123+ let line = state.doc.line(index);
124+ let line_start = state.doc.line_to_char(index);
125+ line_start + line.len_chars() - 1
126+ })
127+ .collect();
128+
129+ let selection = Selection::new(
130+ positions
131+ .iter()
132+ .copied()
133+ .map(|pos| Range::new(pos, pos))
134+ .collect(),
135+ 0,
136+ );
137+
138+ let transaction = Transaction::new(state).with_selection(selection);
139+
140+ transaction.apply(state);
141+ // TODO: need to store into history if successful
142+}
65
143
66// o inserts a new line after each line with a selection
144// o inserts a new line after each line with a selection
67pub fn open_below(state: &mut State, _count: usize) {
145pub fn open_below(state: &mut State, _count: usize) {
helix-core/src/transaction.rs+8
@@ -322,6 +322,14 @@ pub struct Transaction {
322}
322}
323
323
324impl Transaction {
324impl Transaction {
325+ /// Create a new, empty transaction.
326+ pub fn new(state: &mut State) -> Self {
327+ Self {
328+ changes: ChangeSet::new(&state.doc),
329+ selection: None,
330+ }
331+ }
332+
325 /// Returns true if applied successfully.
333 /// Returns true if applied successfully.
326 pub fn apply(&self, state: &mut State) -> bool {
334 pub fn apply(&self, state: &mut State) -> bool {
327 // apply changes to the document
335 // apply changes to the document
helix-term/src/keymap.rs+8
@@ -103,10 +103,18 @@ pub fn default() -> Keymap {
103 code: KeyCode::Char('i'),
103 code: KeyCode::Char('i'),
104 modifiers: Modifiers::NONE
104 modifiers: Modifiers::NONE
105 } => commands::insert_mode as Command,
105 } => commands::insert_mode as Command,
106+ Key {
107+ code: KeyCode::Char('I'),
108+ modifiers: Modifiers::SHIFT,
109+ } => commands::prepend_to_line as Command,
106 Key {
110 Key {
107 code: KeyCode::Char('a'),
111 code: KeyCode::Char('a'),
108 modifiers: Modifiers::NONE
112 modifiers: Modifiers::NONE
109 } => commands::append_mode as Command,
113 } => commands::append_mode as Command,
114+ Key {
115+ code: KeyCode::Char('A'),
116+ modifiers: Modifiers::SHIFT,
117+ } => commands::append_to_line as Command,
110 Key {
118 Key {
111 code: KeyCode::Char('o'),
119 code: KeyCode::Char('o'),
112 modifiers: Modifiers::NONE
120 modifiers: Modifiers::NONE