@@ -315,12 +315,51 @@ fn find_candidates(
315315 offset : usize ,
316316) -> Vec < MatchCandidate > {
317317 let mut candidates = find_contiguous_candidates ( lines, block, offset, false ) ;
318+ if candidates. is_empty ( ) {
319+ candidates = find_single_line_substring_candidates ( lines, block, offset) ;
320+ }
318321 if candidates. is_empty ( ) {
319322 candidates = find_contiguous_candidates ( lines, block, offset, true ) ;
320323 }
321324 candidates
322325}
323326
327+ fn find_single_line_substring_candidates (
328+ lines : & [ String ] ,
329+ block : & SearchReplaceBlock ,
330+ offset : usize ,
331+ ) -> Vec < MatchCandidate > {
332+ if block. search . len ( ) != 1 {
333+ return Vec :: new ( ) ;
334+ }
335+
336+ let search = & block. search [ 0 ] ;
337+ if search. is_empty ( ) {
338+ return Vec :: new ( ) ;
339+ }
340+
341+ let replace = block. replace . join ( "\n " ) ;
342+ lines
343+ . iter ( )
344+ . enumerate ( )
345+ . skip ( offset)
346+ . flat_map ( |( index, line) | {
347+ let replace = replace. clone ( ) ;
348+ line. match_indices ( search) . map ( move |( byte_index, _) | {
349+ let mut replaced_line = line. clone ( ) ;
350+ replaced_line. replace_range ( byte_index..byte_index + search. len ( ) , & replace) ;
351+ MatchCandidate {
352+ start : index,
353+ end : index + 1 ,
354+ score : 0 ,
355+ tolerances : Vec :: new ( ) ,
356+ replace : split_lines ( & replaced_line) ,
357+ }
358+ } )
359+ } )
360+ . collect ( )
361+ }
362+
324363fn find_contiguous_candidates (
325364 lines : & [ String ] ,
326365 block : & SearchReplaceBlock ,
0 commit comments