Implement pair expansion when pressing new line between bracket pairs.

From:
{|}

To:
{
    |
}
pull/11/head
Blaž Hrastnik 4 years ago
parent fd4fd12fa3
commit f8844c6811

@ -3,7 +3,7 @@ use smallvec::SmallVec;
// Heavily based on https://github.com/codemirror/closebrackets/ // Heavily based on https://github.com/codemirror/closebrackets/
const PAIRS: &[(char, char)] = &[ pub const PAIRS: &[(char, char)] = &[
('(', ')'), ('(', ')'),
('{', '}'), ('{', '}'),
('[', ']'), ('[', ']'),

@ -1471,17 +1471,52 @@ pub mod insert {
pub fn insert_newline(cx: &mut Context) { pub fn insert_newline(cx: &mut Context) {
let (view, doc) = cx.current(); let (view, doc) = cx.current();
let text = doc.text().slice(..); let text = doc.text().slice(..);
let transaction =
Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| { let contents = doc.text();
let selection = doc.selection(view.id);
let mut ranges = SmallVec::with_capacity(selection.len());
let mut transaction = Transaction::change_by_selection(contents, selection, |range| {
let pos = range.head; let pos = range.head;
let prev = if pos == 0 {
' '
} else {
contents.char(pos - 1)
};
let curr = contents.char(pos);
// TODO: offset range.head by 1? when calculating? // TODO: offset range.head by 1? when calculating?
let indent_level = indent::suggested_indent_for_pos(doc.syntax(), text, pos, true); let indent_level =
indent::suggested_indent_for_pos(doc.syntax(), text, pos.saturating_sub(1), true);
let indent = doc.indent_unit().repeat(indent_level); let indent = doc.indent_unit().repeat(indent_level);
let mut text = String::with_capacity(1 + indent.len()); let mut text = String::with_capacity(1 + indent.len());
text.push('\n'); text.push('\n');
text.push_str(&indent); text.push_str(&indent);
let head = pos + text.len();
ranges.push(Range::new(
if range.is_empty() { head } else { range.anchor },
head,
));
// if between a bracket pair
if helix_core::auto_pairs::PAIRS.contains(&(prev, curr)) {
// another newline, indent the end bracket one level less
let indent = doc.indent_unit().repeat(indent_level.saturating_sub(1));
text.push('\n');
text.push_str(&indent);
(pos, pos, Some(text.into())) (pos, pos, Some(text.into()))
} else {
(pos, pos, Some(text.into()))
}
}); });
transaction = transaction.with_selection(Selection::new(ranges, selection.primary_index()));
//
doc.apply(&transaction, view.id); doc.apply(&transaction, view.id);
} }

Loading…
Cancel
Save