on master help sign in
Implement pair expansion when pressing new line between bracket pairs.
f8844c6Blaž Hrastnik
helix-core/src/auto_pairs.rs+1−1
@@ -3,7 +3,7 @@ use smallvec::SmallVec;
3
3
4// Heavily based on https://github.com/codemirror/closebrackets/
4// Heavily based on https://github.com/codemirror/closebrackets/
5
5
6−const PAIRS: &[(char, char)] = &[
6+pub const PAIRS: &[(char, char)] = &[
7 ('(', ')'),
7 ('(', ')'),
8 ('{', '}'),
8 ('{', '}'),
9 ('[', ']'),
9 ('[', ']'),
helix-term/src/commands.rs+43−8
@@ -1471,17 +1471,52 @@ pub mod insert {
1471 pub fn insert_newline(cx: &mut Context) {
1471 pub fn insert_newline(cx: &mut Context) {
1472 let (view, doc) = cx.current();
1472 let (view, doc) = cx.current();
1473 let text = doc.text().slice(..);
1473 let text = doc.text().slice(..);
1474− let transaction =
1474+
1475+ let contents = doc.text();
1476+ let selection = doc.selection(view.id);
1477+ let mut ranges = SmallVec::with_capacity(selection.len());
1478+
1475− Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| {
1479+ let mut transaction = Transaction::change_by_selection(contents, selection, |range| {
1476− let pos = range.head;
1480+ let pos = range.head;
1481+
1482+ let prev = if pos == 0 {
1483+ ' '
1484+ } else {
1485+ contents.char(pos - 1)
1486+ };
1487+ let curr = contents.char(pos);
1488+
1477− // TODO: offset range.head by 1? when calculating?
1489+ // TODO: offset range.head by 1? when calculating?
1490+ let indent_level =
1478− let indent_level = indent::suggested_indent_for_pos(doc.syntax(), text, pos, true);
1491+ indent::suggested_indent_for_pos(doc.syntax(), text, pos.saturating_sub(1), true);
1479− let indent = doc.indent_unit().repeat(indent_level);
1492+ let indent = doc.indent_unit().repeat(indent_level);
1480− let mut text = String::with_capacity(1 + indent.len());
1493+ let mut text = String::with_capacity(1 + indent.len());
1494+ text.push('\n');
1495+ text.push_str(&indent);
1496+
1497+ let head = pos + text.len();
1498+
1499+ ranges.push(Range::new(
1500+ if range.is_empty() { head } else { range.anchor },
1501+ head,
1502+ ));
1503+
1504+ // if between a bracket pair
1505+ if helix_core::auto_pairs::PAIRS.contains(&(prev, curr)) {
1506+ // another newline, indent the end bracket one level less
1507+ let indent = doc.indent_unit().repeat(indent_level.saturating_sub(1));
1481 text.push('\n');
1508 text.push('\n');
1482 text.push_str(&indent);
1509 text.push_str(&indent);
1510+
1483 (pos, pos, Some(text.into()))
1511 (pos, pos, Some(text.into()))
1484− });
1512+ } else {
1513+ (pos, pos, Some(text.into()))
1514+ }
1515+ });
1516+
1517+ transaction = transaction.with_selection(Selection::new(ranges, selection.primary_index()));
1518+ //
1519+
1485 doc.apply(&transaction, view.id);
1520 doc.apply(&transaction, view.id);
1486 }
1521 }
1487
1522