Skip to content

Commit

Permalink
Implement open_above (O).
Browse files Browse the repository at this point in the history
  • Loading branch information
archseer committed Mar 22, 2021
1 parent 42d07b0 commit df306fe
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 9 deletions.
2 changes: 1 addition & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
- [ ] CI binary builds

- [ ] regex search / select next
- [ ] open_above (O) command
- [x] open_above (O) command
- [ ] = for auto indent line/selection
- [x] q should only close the view, if all are closed, close the editor
- [ ] buffers should sit on editor.buffers, view simply refs them
Expand Down
57 changes: 50 additions & 7 deletions helix-term/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -869,13 +869,6 @@ pub fn open_below(cx: &mut Context) {
text.push_str(&indent);
let text = text.repeat(count);

// TODO: ideally we want to run a hook over the transactions to figure out and reindent all
// \n's as a post-processing step?
// behaviors:
// - on insert mode enter: we add newline + indent and position cursor at the end
// - on 3o/3O: we insert 3 newlines + indents each and position cursors at ends

// generate changes
(index, index, Some(text.into()))
})
.collect();
Expand All @@ -902,6 +895,56 @@ pub fn open_below(cx: &mut Context) {
}

// O inserts a new line before each line with a selection
pub fn open_above(cx: &mut Context) {
let count = cx.count;
let mut doc = cx.doc();
enter_insert_mode(&mut doc);

let lines = selection_lines(doc.text(), doc.selection());

let positions = lines.into_iter().map(|index| {
// adjust all positions to the end of the previous line
doc.text().line_to_char(index).saturating_sub(1)
});

let text = doc.text().slice(..);

let changes: Vec<Change> = positions
.map(|index| {
// TODO: share logic with insert_newline for indentation
let indent_level =
helix_core::indent::suggested_indent_for_pos(doc.syntax(), text, index, true);
let indent = doc.indent_unit().repeat(indent_level);
let mut text = String::with_capacity(1 + indent.len());
text.push('\n');
text.push_str(&indent);
let text = text.repeat(count);

// generate changes
(index, index, Some(text.into()))
})
.collect();

// TODO: count actually inserts "n" new lines and starts editing on all of them.
// TODO: append "count" newlines and modify cursors to those lines

let selection = Selection::new(
changes
.iter()
.map(|(start, _end, text): &Change| {
let len = text.as_ref().map(|text| text.len()).unwrap(); // minus newline
let pos = start + len;
Range::new(pos, pos)
})
.collect(),
0,
);

let transaction =
Transaction::change(doc.text(), changes.into_iter()).with_selection(selection);

doc.apply(&transaction);
}

pub fn normal_mode(cx: &mut Context) {
let mut doc = cx.doc();
Expand Down
2 changes: 1 addition & 1 deletion helix-term/src/keymap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ pub fn default() -> Keymaps {
key!('a') => commands::append_mode,
shift!('A') => commands::append_to_line,
key!('o') => commands::open_below,
// key!('O') => commands::open_above,
shift!('O') => commands::open_above,
// [<space> ]<space> equivalents too (add blank new line, no edit)


Expand Down

0 comments on commit df306fe

Please sign in to comment.