Support m in surround delete and replace

This commit is contained in:
Gokul Soumya 2022-04-03 22:00:26 +05:30 committed by Blaž Hrastnik
parent de15d70171
commit 76175dbd6d
2 changed files with 16 additions and 9 deletions

View file

@ -212,17 +212,22 @@ fn find_nth_close_pair(
/// Find position of surround characters around every cursor. Returns None /// Find position of surround characters around every cursor. Returns None
/// if any positions overlap. Note that the positions are in a flat Vec. /// if any positions overlap. Note that the positions are in a flat Vec.
/// Use get_surround_pos().chunks(2) to get matching pairs of surround positions. /// Use get_surround_pos().chunks(2) to get matching pairs of surround positions.
/// `ch` can be either closing or opening pair. /// `ch` can be either closing or opening pair. If `ch` is None, surround pairs
/// are automatically detected around each cursor (note that this may result
/// in them selecting different surround characters for each selection).
pub fn get_surround_pos( pub fn get_surround_pos(
text: RopeSlice, text: RopeSlice,
selection: &Selection, selection: &Selection,
ch: char, ch: Option<char>,
skip: usize, skip: usize,
) -> Result<Vec<usize>> { ) -> Result<Vec<usize>> {
let mut change_pos = Vec::new(); let mut change_pos = Vec::new();
for &range in selection { for &range in selection {
let (open_pos, close_pos) = find_nth_pairs_pos(text, ch, range, skip)?; let (open_pos, close_pos) = match ch {
Some(ch) => find_nth_pairs_pos(text, ch, range, skip)?,
None => find_nth_closest_pairs_pos(text, range, skip)?,
};
if change_pos.contains(&open_pos) || change_pos.contains(&close_pos) { if change_pos.contains(&open_pos) || change_pos.contains(&close_pos) {
return Err(Error::CursorOverlap); return Err(Error::CursorOverlap);
} }

View file

@ -4111,15 +4111,16 @@ fn surround_add(cx: &mut Context) {
fn surround_replace(cx: &mut Context) { fn surround_replace(cx: &mut Context) {
let count = cx.count(); let count = cx.count();
cx.on_next_key(move |cx, event| { cx.on_next_key(move |cx, event| {
let from = match event.char() { let surround_ch = match event.char() {
Some(from) => from, Some('m') => None, // m selects the closest surround pair
Some(ch) => Some(ch),
None => return, None => return,
}; };
let (view, doc) = current!(cx.editor); let (view, doc) = current!(cx.editor);
let text = doc.text().slice(..); let text = doc.text().slice(..);
let selection = doc.selection(view.id); let selection = doc.selection(view.id);
let change_pos = match surround::get_surround_pos(text, selection, from, count) { let change_pos = match surround::get_surround_pos(text, selection, surround_ch, count) {
Ok(c) => c, Ok(c) => c,
Err(err) => { Err(err) => {
cx.editor.set_error(err.to_string()); cx.editor.set_error(err.to_string());
@ -4150,15 +4151,16 @@ fn surround_replace(cx: &mut Context) {
fn surround_delete(cx: &mut Context) { fn surround_delete(cx: &mut Context) {
let count = cx.count(); let count = cx.count();
cx.on_next_key(move |cx, event| { cx.on_next_key(move |cx, event| {
let ch = match event.char() { let surround_ch = match event.char() {
Some(ch) => ch, Some('m') => None, // m selects the closest surround pair
Some(ch) => Some(ch),
None => return, None => return,
}; };
let (view, doc) = current!(cx.editor); let (view, doc) = current!(cx.editor);
let text = doc.text().slice(..); let text = doc.text().slice(..);
let selection = doc.selection(view.id); let selection = doc.selection(view.id);
let change_pos = match surround::get_surround_pos(text, selection, ch, count) { let change_pos = match surround::get_surround_pos(text, selection, surround_ch, count) {
Ok(c) => c, Ok(c) => c,
Err(err) => { Err(err) => {
cx.editor.set_error(err.to_string()); cx.editor.set_error(err.to_string());