on master help sign in
Implement open_above (O).
commitdf306fe031e6ddb188cda9d33da019b65af8cd99 authorBlaž Hrastnik <blaz@mxxn.io> dateSat 20 Mar 2021, 00:16 (6 years ago) parent42d07b0
3 files changed+52−9
TODO.md+1−1 helix-term/src/commands.rs+50−7 helix-term/src/keymap.rs+1−1
TODO.md+1−1
@@ -16,7 +16,7 @@
1616- [ ] CI binary builds
1717
1818- [ ] regex search / select next
19−- [ ] open_above (O) command
19+- [x] open_above (O) command
2020- [ ] = for auto indent line/selection
2121- [x] q should only close the view, if all are closed, close the editor
2222- [ ] buffers should sit on editor.buffers, view simply refs them
helix-term/src/commands.rs+50−7
@@ -869,13 +869,6 @@ pub fn open_below(cx: &mut Context) {
869869 text.push_str(&indent);
870870 let text = text.repeat(count);
871871
872− // TODO: ideally we want to run a hook over the transactions to figure out and reindent all
873− // \n's as a post-processing step?
874− // behaviors:
875− // - on insert mode enter: we add newline + indent and position cursor at the end
876− // - on 3o/3O: we insert 3 newlines + indents each and position cursors at ends
877−
878− // generate changes
879872 (index, index, Some(text.into()))
880873 })
881874 .collect();
@@ -902,6 +895,56 @@ pub fn open_below(cx: &mut Context) {
902895}
903896
904897// O inserts a new line before each line with a selection
898+pub fn open_above(cx: &mut Context) {
899+ let count = cx.count;
900+ let mut doc = cx.doc();
901+ enter_insert_mode(&mut doc);
902+
903+ let lines = selection_lines(doc.text(), doc.selection());
904+
905+ let positions = lines.into_iter().map(|index| {
906+ // adjust all positions to the end of the previous line
907+ doc.text().line_to_char(index).saturating_sub(1)
908+ });
909+
910+ let text = doc.text().slice(..);
911+
912+ let changes: Vec<Change> = positions
913+ .map(|index| {
914+ // TODO: share logic with insert_newline for indentation
915+ let indent_level =
916+ helix_core::indent::suggested_indent_for_pos(doc.syntax(), text, index, true);
917+ let indent = doc.indent_unit().repeat(indent_level);
918+ let mut text = String::with_capacity(1 + indent.len());
919+ text.push('\n');
920+ text.push_str(&indent);
921+ let text = text.repeat(count);
922+
923+ // generate changes
924+ (index, index, Some(text.into()))
925+ })
926+ .collect();
927+
928+ // TODO: count actually inserts "n" new lines and starts editing on all of them.
929+ // TODO: append "count" newlines and modify cursors to those lines
930+
931+ let selection = Selection::new(
932+ changes
933+ .iter()
934+ .map(|(start, _end, text): &Change| {
935+ let len = text.as_ref().map(|text| text.len()).unwrap(); // minus newline
936+ let pos = start + len;
937+ Range::new(pos, pos)
938+ })
939+ .collect(),
940+ 0,
941+ );
942+
943+ let transaction =
944+ Transaction::change(doc.text(), changes.into_iter()).with_selection(selection);
945+
946+ doc.apply(&transaction);
947+}
905948
906949pub fn normal_mode(cx: &mut Context) {
907950 let mut doc = cx.doc();
helix-term/src/keymap.rs+1−1
@@ -160,7 +160,7 @@ pub fn default() -> Keymaps {
160160 key!('a') => commands::append_mode,
161161 shift!('A') => commands::append_to_line,
162162 key!('o') => commands::open_below,
163− // key!('O') => commands::open_above,
163+ shift!('O') => commands::open_above,
164164 // [<space> ]<space> equivalents too (add blank new line, no edit)
165165
166166