@@ -353,7 +353,7 @@ impl LineCompleter {
353353}
354354
355355mod parse {
356- use std:: borrow:: Cow ;
356+ use std:: { borrow:: Cow , path :: MAIN_SEPARATOR } ;
357357
358358 use nom:: {
359359 branch:: alt,
@@ -412,6 +412,25 @@ mod parse {
412412
413413 filepath_at_end ( prefix. as_ref ( ) ) . ok ( ) . map ( |( _, path) | path)
414414 }
415+
416+ pub fn escape_string ( input : & mut String ) {
417+ for c in [ "\\ \\ " , "\\ " , "\\ #" , "\\ %" , "\\ |" , "\\ \" " ] {
418+ if input. contains ( & c[ 1 ..2 ] ) {
419+ * input = input. replace ( & c[ 1 ..2 ] , c) ;
420+ }
421+ }
422+ }
423+
424+ pub fn trailing_filename ( input : & str ) -> & str {
425+ let start = input. rfind ( MAIN_SEPARATOR ) . map ( |s| s + 1 ) . unwrap_or ( 0 ) ;
426+ & input[ start..]
427+ }
428+
429+ pub fn trailing_filename_escaped ( input : & str ) -> String {
430+ let mut name = trailing_filename ( input) . to_string ( ) ;
431+ escape_string ( & mut name) ;
432+ name
433+ }
415434}
416435
417436/// Complete filenames within a path leading up to the cursor.
@@ -430,7 +449,7 @@ pub fn complete_path(input: &EditRope, cursor: &mut Cursor) -> Vec<String> {
430449 }
431450
432451 if filepath. is_empty ( ) {
433- filepath = Cow :: Borrowed ( "./" ) ;
452+ filepath = format ! ( ".{MAIN_SEPARATOR}" ) . into ( ) ;
434453 }
435454
436455 let mut res = Vec :: < String > :: with_capacity ( MAX_COMPLETIONS ) ;
@@ -462,10 +481,10 @@ pub fn complete_path(input: &EditRope, cursor: &mut Cursor) -> Vec<String> {
462481 filepath. strip_suffix ( '.' ) . is_some_and ( |s| s. ends_with ( MAIN_SEPARATOR ) )
463482 {
464483 // complete all dotfiles
465-
466484 // The .parent() and .file_name() methods treat . especially, so we
467485 // have to special-case completion of hidden files here.
468- let _ = input. get_prefix_word_mut ( cursor, & WordStyle :: CharSet ( |c| c != MAIN_SEPARATOR ) ) ; // TODO: fix for windows
486+
487+ cursor. left ( parse:: trailing_filename_escaped ( filepath. as_ref ( ) ) . len ( ) ) ;
469488
470489 if let Ok ( dir) = path. read_dir ( ) {
471490 let filter = |entry : DirEntry | {
@@ -491,8 +510,7 @@ pub fn complete_path(input: &EditRope, cursor: &mut Cursor) -> Vec<String> {
491510 }
492511 } else {
493512 // complete a path
494-
495- let _ = input. get_prefix_word_mut ( cursor, & WordStyle :: CharSet ( |c| c != MAIN_SEPARATOR ) ) ; // TODO: fix for windows
513+ cursor. left ( parse:: trailing_filename_escaped ( filepath. as_ref ( ) ) . len ( ) ) ;
496514
497515 let Some ( prefix) = path. components ( ) . next_back ( ) else {
498516 return vec ! [ ] ;
@@ -561,11 +579,7 @@ pub fn complete_path(input: &EditRope, cursor: &mut Cursor) -> Vec<String> {
561579 } ) ;
562580
563581 for comp in & mut res {
564- for c in [ "\\ \\ " , "\\ " , "\\ #" , "\\ %" , "\\ |" , "\\ \" " ] {
565- if comp. contains ( & c[ 1 ..2 ] ) {
566- * comp = comp. replace ( & c[ 1 ..2 ] , c) ;
567- }
568- }
582+ parse:: escape_string ( comp) ;
569583 }
570584
571585 return res;
0 commit comments