@@ -288,25 +288,19 @@ async fn generate_completion_scripts(
288288 let completion_dir = vite_plus_home. join ( "completion" ) ;
289289 tokio:: fs:: create_dir_all ( & completion_dir) . await ?;
290290
291- // Bash completion
292- let bash_completion = completion_dir. join ( "vp.bash" ) ;
293- let mut bash_file = std:: fs:: File :: create ( & bash_completion) ?;
294- clap_complete:: generate ( clap_complete:: Shell :: Bash , & mut cmd, "vp" , & mut bash_file) ;
295-
296- // Zsh completion (following zsh convention: _vp)
297- let zsh_completion = completion_dir. join ( "_vp" ) ;
298- let mut zsh_file = std:: fs:: File :: create ( & zsh_completion) ?;
299- clap_complete:: generate ( clap_complete:: Shell :: Zsh , & mut cmd, "vp" , & mut zsh_file) ;
300-
301- // Fish completion
302- let fish_completion = completion_dir. join ( "vp.fish" ) ;
303- let mut fish_file = std:: fs:: File :: create ( & fish_completion) ?;
304- clap_complete:: generate ( clap_complete:: Shell :: Fish , & mut cmd, "vp" , & mut fish_file) ;
305-
306- // PowerShell completion
307- let ps1_completion = completion_dir. join ( "vp.ps1" ) ;
308- let mut ps1_file = std:: fs:: File :: create ( & ps1_completion) ?;
309- clap_complete:: generate ( clap_complete:: Shell :: PowerShell , & mut cmd, "vp" , & mut ps1_file) ;
291+ // Generate shell completion scripts
292+ let completions = [
293+ ( clap_complete:: Shell :: Bash , "vp.bash" ) ,
294+ ( clap_complete:: Shell :: Zsh , "_vp" ) ,
295+ ( clap_complete:: Shell :: Fish , "vp.fish" ) ,
296+ ( clap_complete:: Shell :: PowerShell , "vp.ps1" ) ,
297+ ] ;
298+
299+ for ( shell, filename) in completions {
300+ let path = completion_dir. join ( filename) ;
301+ let mut file = std:: fs:: File :: create ( & path) ?;
302+ clap_complete:: generate ( shell, & mut cmd, "vp" , & mut file) ;
303+ }
310304
311305 tracing:: debug!( "Generated completion scripts in {:?}" , completion_dir) ;
312306
@@ -430,11 +424,13 @@ async fn create_env_files(vite_plus_home: &vite_path::AbsolutePath) -> Result<()
430424 home_dir
431425 . as_ref ( )
432426 . and_then ( |h| path. as_path ( ) . strip_prefix ( h) . ok ( ) )
433- . map ( |s| format ! ( "$HOME/{}" , s. display( ) ) )
427+ . map ( |s| {
428+ // Normalize to forward slashes for $HOME/... paths (POSIX-style)
429+ format ! ( "$HOME/{}" , s. display( ) . to_string( ) . replace( '\\' , "/" ) )
430+ } )
434431 . unwrap_or_else ( || path. as_path ( ) . display ( ) . to_string ( ) )
435432 } ;
436433 let bin_path_ref = to_ref ( & bin_path) ;
437- let completion_path_ref = to_ref ( & completion_path) ;
438434
439435 // POSIX env file (bash/zsh)
440436 // When sourced multiple times, removes existing entry and re-prepends to front
@@ -492,8 +488,8 @@ elif [ -n "$ZSH_VERSION" ] && type compdef >/dev/null 2>&1; then
492488fi
493489"#
494490 . replace ( "__VP_BIN__" , & bin_path_ref)
495- . replace ( "__VP_COMPLETION_BASH__" , & format ! ( "{}/ vp.bash", completion_path_ref ) )
496- . replace ( "__VP_COMPLETION_ZSH__" , & format ! ( "{}/ _vp", completion_path_ref ) ) ;
491+ . replace ( "__VP_COMPLETION_BASH__" , & to_ref ( & completion_path . join ( " vp.bash") ) )
492+ . replace ( "__VP_COMPLETION_ZSH__" , & to_ref ( & completion_path . join ( " _vp") ) ) ;
497493 let env_file = vite_plus_home. join ( "env" ) ;
498494 tokio:: fs:: write ( & env_file, env_content) . await ?;
499495
@@ -525,7 +521,7 @@ if test -f "$__vp_completion"
525521end
526522"#
527523 . replace ( "__VP_BIN__" , & bin_path_ref)
528- . replace ( "__VP_COMPLETION_FISH__" , & format ! ( "{}/ vp.fish", completion_path_ref ) ) ;
524+ . replace ( "__VP_COMPLETION_FISH__" , & to_ref ( & completion_path . join ( " vp.fish") ) ) ;
529525 let env_fish_file = vite_plus_home. join ( "env.fish" ) ;
530526 tokio:: fs:: write ( & env_fish_file, env_fish_content) . await ?;
531527
@@ -569,10 +565,10 @@ if (Test-Path $__vp_completion) {
569565
570566 // For PowerShell, use the actual absolute path (not $HOME-relative)
571567 let bin_path_win = bin_path. as_path ( ) . display ( ) . to_string ( ) ;
572- let completion_path_win = completion_path. as_path ( ) . display ( ) . to_string ( ) ;
568+ let completion_ps1_win = completion_path. join ( "vp.ps1" ) . as_path ( ) . display ( ) . to_string ( ) ;
573569 let env_ps1_content = env_ps1_content
574570 . replace ( "__VP_BIN_WIN__" , & bin_path_win)
575- . replace ( "__VP_COMPLETION_PS1__" , & format ! ( "{}/vp.ps1" , completion_path_win ) ) ;
571+ . replace ( "__VP_COMPLETION_PS1__" , & completion_ps1_win ) ;
576572 let env_ps1_file = vite_plus_home. join ( "env.ps1" ) ;
577573 tokio:: fs:: write ( & env_ps1_file, env_ps1_content) . await ?;
578574
@@ -952,7 +948,11 @@ mod tests {
952948 ) ;
953949 assert ! (
954950 ps1_content. contains( "Shell completion" )
955- && ps1_content. contains( "/completion/vp.ps1\" " ) ,
951+ && ps1_content. contains( & format!(
952+ "{}completion{}vp.ps1\" " ,
953+ std:: path:: MAIN_SEPARATOR_STR ,
954+ std:: path:: MAIN_SEPARATOR_STR
955+ ) ) ,
956956 "env.ps1 file should contain PowerShell completion"
957957 ) ;
958958
0 commit comments