Skip to content

Commit

Permalink
Fix cursor position bugs related to o and O
Browse files Browse the repository at this point in the history
- `O` at the beginning of file didn't move cursor
- `o` and `O` messed up cursor position with multiple cursors

Fixes #127
  • Loading branch information
sudormrfbin authored and archseer committed Jun 17, 2021
1 parent a364d6c commit 20d6b20
Showing 1 changed file with 37 additions and 35 deletions.
72 changes: 37 additions & 35 deletions helix-term/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1495,53 +1495,55 @@ fn open(cx: &mut Context, open: Open) {
enter_insert_mode(doc);

let text = doc.text().slice(..);
let contents = doc.text();
let selection = doc.selection(view.id);

let mut ranges = SmallVec::with_capacity(selection.len());
let mut offs = 0;

let changes: Vec<Change> = selection
.iter()
.map(|range| {
let line = text.char_to_line(range.head);

let line = match open {
// adjust position to the end of the line (next line - 1)
Open::Below => line + 1,
// adjust position to the end of the previous line (current line - 1)
Open::Above => line,
};
let mut transaction = Transaction::change_by_selection(contents, selection, |range| {
let line = text.char_to_line(range.head);

let index = doc.text().line_to_char(line).saturating_sub(1);
let line = match open {
// adjust position to the end of the line (next line - 1)
Open::Below => line + 1,
// adjust position to the end of the previous line (current line - 1)
Open::Above => line,
};

// TODO: share logic with insert_newline for indentation
let indent_level = indent::suggested_indent_for_pos(
doc.language_config(),
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);
let index = doc.text().line_to_char(line).saturating_sub(1);

// calculate new selection range
let pos = index + text.chars().count();
ranges.push(Range::new(pos, pos));
// TODO: share logic with insert_newline for indentation
let indent_level = indent::suggested_indent_for_pos(
doc.language_config(),
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);

// calculate new selection range
let pos = if line == 0 {
0 // Required since text will have a min len of 1 (\n)
} else {
index + offs + text.chars().count()
};
ranges.push(Range::new(pos, pos));

(index, index, Some(text.into()))
})
.collect();
offs += text.chars().count();

(index, index, Some(text.into()))
});

// 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(ranges, 0);

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

doc.apply(&transaction, view.id);
}
Expand Down

0 comments on commit 20d6b20

Please sign in to comment.