@@ -250,18 +250,27 @@ pub mod util {
250250 /// If the LS did not provide a range for the completion or the range of the
251251 /// primary cursor can not be used for the secondary cursor, this function
252252 /// can be used to find the completion range for a cursor
253− fn find_completion_range(text: RopeSlice, cursor: usize) -> (usize, usize) {
253+ fn find_completion_range(text: RopeSlice, replace_mode: bool, cursor: usize) -> (usize, usize) {
254254 let start = cursor
255255 - text
256256 .chars_at(cursor)
257257 .reversed()
258258 .take_while(|ch| chars::char_is_word(*ch))
259259 .count();
260− (start, cursor)
260+ let mut end = cursor;
261+ if replace_mode {
262+ end += text
263+ .chars_at(cursor)
264+ .skip(1)
265+ .take_while(|ch| chars::char_is_word(*ch))
266+ .count();
267+ }
268+ (start, end)
261269 }
262270 fn completion_range(
263271 text: RopeSlice,
264272 edit_offset: Option<(i128, i128)>,
273+ replace_mode: bool,
265274 cursor: usize,
266275 ) -> Option<(usize, usize)> {
267276 let res = match edit_offset {
@@ -276,7 +285,7 @@ pub mod util {
276285 }
277286 (start_offset as usize, end_offset as usize)
278287 }
279− None => find_completion_range(text, cursor),
288+ None => find_completion_range(text, replace_mode, cursor),
280289 };
281290 Some(res)
282291 }
@@ -287,6 +296,7 @@ pub mod util {
287296 doc: &Rope,
288297 selection: &Selection,
289298 edit_offset: Option<(i128, i128)>,
299+ replace_mode: bool,
290300 new_text: String,
291301 ) -> Transaction {
292302 let replacement: Option<Tendril> = if new_text.is_empty() {
@@ -296,9 +306,13 @@ pub mod util {
296306 };
297307
298308 let text = doc.slice(..);
299− let (removed_start, removed_end) =
300− completion_range(text, edit_offset, selection.primary().cursor(text))
301− .expect("transaction must be valid for primary selection");
309+ let (removed_start, removed_end) = completion_range(
310+ text,
311+ edit_offset,
312+ replace_mode,
313+ selection.primary().cursor(text),
314+ )
315+ .expect("transaction must be valid for primary selection");
302316 let removed_text = text.slice(removed_start..removed_end);
303317
304318 let (transaction, mut selection) = Transaction::change_by_selection_ignore_overlapping(
@@ -306,9 +320,9 @@ pub mod util {
306320 selection,
307321 |range| {
308322 let cursor = range.cursor(text);
309− completion_range(text, edit_offset, cursor)
323+ completion_range(text, edit_offset, replace_mode, cursor)
310324 .filter(|(start, end)| text.slice(start..end) == removed_text)
311− .unwrap_or_else(|| find_completion_range(text, cursor))
325+ .unwrap_or_else(|| find_completion_range(text, replace_mode, cursor))
312326 },
313327 |_, _| replacement.clone(),
314328 );
@@ -326,6 +340,7 @@ pub mod util {
326340 doc: &Rope,
327341 selection: &Selection,
328342 edit_offset: Option<(i128, i128)>,
343+ replace_mode: bool,
329344 snippet: snippet::Snippet,
330345 line_ending: &str,
331346 include_placeholder: bool,
@@ -336,9 +351,13 @@ pub mod util {
336351 let mut off = 0i128;
337352 let mut mapped_doc = doc.clone();
338353 let mut selection_tabstops: SmallVec<[_; 1]> = SmallVec::new();
339− let (removed_start, removed_end) =
340− completion_range(text, edit_offset, selection.primary().cursor(text))
341− .expect("transaction must be valid for primary selection");
354+ let (removed_start, removed_end) = completion_range(
355+ text,
356+ edit_offset,
357+ replace_mode,
358+ selection.primary().cursor(text),
359+ )
360+ .expect("transaction must be valid for primary selection");
342361 let removed_text = text.slice(removed_start..removed_end);
343362
344363 let (transaction, selection) = Transaction::change_by_selection_ignore_overlapping(
@@ -346,9 +365,9 @@ pub mod util {
346365 selection,
347366 |range| {
348367 let cursor = range.cursor(text);
349− completion_range(text, edit_offset, cursor)
368+ completion_range(text, edit_offset, replace_mode, cursor)
350369 .filter(|(start, end)| text.slice(start..end) == removed_text)
351− .unwrap_or_else(|| find_completion_range(text, cursor))
370+ .unwrap_or_else(|| find_completion_range(text, replace_mode, cursor))
352371 },
353372 |replacement_start, replacement_end| {
354373 let mapped_replacement_start = (replacement_start as i128 + off) as usize;