@@ -307,15 +307,22 @@ impl ColumnarMenu {
307307 . unwrap_or ( shortest_base) ;
308308 let match_len = shortest_base. len ( ) ;
309309
310- // Split string so the match text can be styled
311- let skip_len = suggestion
310+ // Find match position - look for the base string in the suggestion (case-insensitive)
311+ let match_position = suggestion
312312 . value
313- . chars ( )
314- . take_while ( |c| is_quote ( * c) )
315- . count ( ) ;
316- let ( match_str, remaining_str) = suggestion
317- . value
318- . split_at ( ( match_len + skip_len) . min ( suggestion. value . len ( ) ) ) ;
313+ . to_lowercase ( )
314+ . find ( & shortest_base. to_lowercase ( ) )
315+ . unwrap_or ( 0 ) ;
316+
317+ // The match is just the part that matches the shortest_base
318+ let match_str = & suggestion. value [ match_position
319+ ..match_position + match_len. min ( suggestion. value . len ( ) - match_position) ] ;
320+
321+ // Prefix is everything before the match
322+ let prefix = & suggestion. value [ ..match_position] ;
323+
324+ // Remaining is everything after the match
325+ let remaining_str = & suggestion. value [ match_position + match_str. len ( ) ..] ;
319326
320327 let suggestion_style_prefix = suggestion
321328 . style
@@ -325,20 +332,24 @@ impl ColumnarMenu {
325332 let left_text_size = self . longest_suggestion + self . default_details . col_padding ;
326333 let right_text_size = self . get_width ( ) . saturating_sub ( left_text_size) ;
327334
328- let max_remaining = left_text_size. saturating_sub ( match_str. width ( ) ) ;
335+ let max_remaining = left_text_size. saturating_sub ( match_str. width ( ) + prefix . width ( ) ) ;
329336 let max_match = max_remaining. saturating_sub ( remaining_str. width ( ) ) ;
330337
331338 if index == self . index ( ) {
332339 if let Some ( description) = & suggestion. description {
333340 format ! (
334- "{}{}{}{}{}{:max_match$}{:max_remaining$}{}{}{}{}{}{}" ,
341+ "{}{}{}{}{}{}{}{}{}{:max_match$}{:max_remaining$}{}{}{}{}{}{}" ,
342+ suggestion_style_prefix,
343+ self . settings. color. selected_text_style. prefix( ) ,
344+ prefix,
345+ RESET ,
335346 suggestion_style_prefix,
336347 self . settings. color. selected_match_style. prefix( ) ,
337348 match_str,
338349 RESET ,
339350 suggestion_style_prefix,
340351 self . settings. color. selected_text_style. prefix( ) ,
341- & remaining_str,
352+ remaining_str,
342353 RESET ,
343354 self . settings. color. description_style. prefix( ) ,
344355 self . settings. color. selected_text_style. prefix( ) ,
@@ -352,7 +363,11 @@ impl ColumnarMenu {
352363 )
353364 } else {
354365 format ! (
355- "{}{}{}{}{}{}{}{}{:>empty$}{}" ,
366+ "{}{}{}{}{}{}{}{}{}{}{}{}{:>empty$}{}" ,
367+ suggestion_style_prefix,
368+ self . settings. color. selected_text_style. prefix( ) ,
369+ prefix,
370+ RESET ,
356371 suggestion_style_prefix,
357372 self . settings. color. selected_match_style. prefix( ) ,
358373 match_str,
@@ -368,7 +383,10 @@ impl ColumnarMenu {
368383 }
369384 } else if let Some ( description) = & suggestion. description {
370385 format ! (
371- "{}{}{}{}{:max_match$}{:max_remaining$}{}{}{}{}{}" ,
386+ "{}{}{}{}{}{}{}{:max_match$}{:max_remaining$}{}{}{}{}{}" ,
387+ suggestion_style_prefix,
388+ prefix,
389+ RESET ,
372390 suggestion_style_prefix,
373391 self . settings. color. match_style. prefix( ) ,
374392 match_str,
@@ -387,7 +405,10 @@ impl ColumnarMenu {
387405 )
388406 } else {
389407 format ! (
390- "{}{}{}{}{}{}{}{}{:>empty$}{}{}" ,
408+ "{}{}{}{}{}{}{}{}{}{}{}{:>empty$}{}{}" ,
409+ suggestion_style_prefix,
410+ prefix,
411+ RESET ,
391412 suggestion_style_prefix,
392413 self . settings. color. match_style. prefix( ) ,
393414 match_str,
@@ -796,6 +817,6 @@ mod tests {
796817
797818 editor. set_buffer ( "おは" . to_string ( ) , UndoBehavior :: CreateUndoPoint ) ;
798819 menu. update_values ( & mut editor, & mut completer) ;
799- assert ! ( menu. menu_string( 2 , true ) . contains( "` おは" ) ) ;
820+ assert ! ( menu. menu_string( 2 , true ) . contains( "おは" ) ) ;
800821 }
801822}
0 commit comments