Skip to content

Commit c379463

Browse files
committed
refactor(vim): avoid overlapping edits on change surrounds
Update `Vim.change_surround` in order to ensure that there's no overlapping edits by keeping track of where the open string range ends and ensuring that the closing string range start does not go lower than the open string range end.
1 parent f36b843 commit c379463

File tree

1 file changed

+12
-15
lines changed

1 file changed

+12
-15
lines changed

crates/vim/src/surrounds.rs

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -282,20 +282,20 @@ impl Vim {
282282
// that the end replacement string does not exceed
283283
// this value. Helpful when dealing with newlines.
284284
let mut edit_len = 0;
285-
let mut forward_end: Option<usize> = None;
286285
let mut chars_and_offset = display_map
287286
.buffer_chars_at(range.start.to_offset(&display_map, Bias::Left))
288287
.peekable();
289288

289+
let mut open_end = 0;
290290
while let Some((ch, offset)) = chars_and_offset.next() {
291291
if ch.to_string() == will_replace_pair.start {
292292
let mut open_str = pair.start.clone();
293293
let start = offset;
294-
let mut end = start + 1;
294+
open_end = start + 1;
295295
while let Some((next_ch, _)) = chars_and_offset.next()
296-
&& next_ch.to_string() == " "
296+
&& next_ch == ' '
297297
{
298-
end += 1;
298+
open_end += 1;
299299

300300
if preserve_space {
301301
open_str.push(next_ch);
@@ -306,10 +306,9 @@ impl Vim {
306306
open_str.push(' ');
307307
};
308308

309-
edit_len = end - start;
310-
edits.push((start..end, open_str));
309+
edit_len = open_end - start;
310+
edits.push((start..open_end, open_str));
311311
anchors.push(start..start);
312-
forward_end = Some(end);
313312
break;
314313
}
315314
}
@@ -321,27 +320,25 @@ impl Vim {
321320
.peekable();
322321
while let Some((ch, offset)) = reverse_chars_and_offsets.next() {
323322
if ch.to_string() == will_replace_pair.end {
324-
let mut close_str = String::new();
323+
let mut close_str = pair.end.clone();
325324
let mut start = offset;
326325
let end = start + 1;
327326
while let Some((next_ch, _)) = reverse_chars_and_offsets.next()
328-
&& (next_ch.to_string() == " "
329-
&& forward_end
330-
.map_or(true, |open_end| start > open_end))
331-
&& close_str.len() < edit_len - 1
327+
&& next_ch == ' '
328+
&& close_str.len() < edit_len
329+
&& start > open_end
332330
{
333331
start -= 1;
334332

335333
if preserve_space {
336-
close_str.push(next_ch);
334+
close_str.insert(0, next_ch);
337335
}
338336
}
339337

340338
if add_space {
341-
close_str.push(' ');
339+
close_str.insert(0, ' ');
342340
};
343341

344-
close_str.push_str(&pair.end);
345342
edits.push((start..end, close_str));
346343
break;
347344
}

0 commit comments

Comments
 (0)