Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-core/src/auto_pairs.rs')
| -rw-r--r-- | helix-core/src/auto_pairs.rs | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/helix-core/src/auto_pairs.rs b/helix-core/src/auto_pairs.rs index fb918a9a..37d3a2dd 100644 --- a/helix-core/src/auto_pairs.rs +++ b/helix-core/src/auto_pairs.rs @@ -127,6 +127,8 @@ pub fn hook_insert( // && char_at pos == close return handle_insert_close(doc, range, pair); } + } else if ch.is_whitespace() { + return handle_insert_whitespace(doc, range, ch, pairs); } None @@ -139,12 +141,33 @@ pub fn hook_delete(doc: &Rope, range: &Range, pairs: &AutoPairs) -> Option<(Dele let cur = doc.get_char(cursor)?; let prev = prev_char(doc, cursor)?; + + // check for whitespace surrounding a pair + if doc.len_chars() >= 4 && prev.is_whitespace() && cur.is_whitespace() { + let second_prev = doc.get_char(graphemes::nth_prev_grapheme_boundary(text, cursor, 2))?; + let second_next = doc.get_char(graphemes::next_grapheme_boundary(text, cursor))?; + log::debug!("second_prev: {}, second_next: {}", second_prev, second_next); + + if let Some(pair) = pairs.get(second_prev) { + if pair.open == second_prev && pair.close == second_next { + return handle_delete(doc, range); + } + } + } + let pair = pairs.get(cur)?; - if pair.open != prev { + if pair.open != prev || pair.close != cur { return None; } + handle_delete(doc, range) +} + +pub fn handle_delete(doc: &Rope, range: &Range) -> Option<(Deletion, Range)> { + let text = doc.slice(..); + let cursor = range.cursor(text); + let end_next = graphemes::next_grapheme_boundary(text, cursor); let end_prev = graphemes::prev_grapheme_boundary(text, cursor); @@ -162,6 +185,30 @@ pub fn hook_delete(doc: &Rope, range: &Range, pairs: &AutoPairs) -> Option<(Dele Some((delete, next_range)) } +fn handle_insert_whitespace( + doc: &Rope, + range: &Range, + ch: char, + pairs: &AutoPairs, +) -> Option<(Change, Range)> { + let text = doc.slice(..); + let cursor = range.cursor(text); + let cur = doc.get_char(cursor)?; + let prev = prev_char(doc, cursor)?; + let pair = pairs.get(cur)?; + + if pair.open != prev || pair.close != cur { + return None; + } + + let whitespace_pair = Pair { + open: ch, + close: ch, + }; + + handle_insert_same(doc, range, &whitespace_pair) +} + fn prev_char(doc: &Rope, pos: usize) -> Option<char> { if pos == 0 { return None; |