@@ -58,7 +58,7 @@ fn cargo_home_str_with_home(home: &str, process: &Process) -> Result<Cow<'static
5858}
5959
6060// TODO: Tcsh (BSD)
61- // TODO?: Make a decision on Ion Shell, Power Shell, Nushell
61+ // TODO?: Make a decision on Ion Shell
6262// Cross-platform non-POSIX shells have not been assessed for integration yet
6363fn enumerate_shells ( ) -> Vec < Shell > {
6464 vec ! [
@@ -68,6 +68,7 @@ fn enumerate_shells() -> Vec<Shell> {
6868 Box :: new( Fish ) ,
6969 Box :: new( Nu ) ,
7070 Box :: new( Tcsh ) ,
71+ Box :: new( Pwsh ) ,
7172 ]
7273}
7374
@@ -368,6 +369,82 @@ impl UnixShell for Tcsh {
368369 }
369370}
370371
372+ struct Pwsh ;
373+
374+ impl UnixShell for Pwsh {
375+ fn does_exist ( & self , process : & Process ) -> bool {
376+ matches ! ( process. var( "SHELL" ) , Ok ( sh) if sh. contains( "pwsh" ) )
377+ || utils:: find_cmd ( & [ "pwsh" ] , process) . is_some ( )
378+ }
379+
380+ fn rcfiles ( & self , process : & Process ) -> Vec < PathBuf > {
381+ let mut paths = vec ! [ ] ;
382+
383+ let Some ( mut config_dir) = process. home_dir ( ) else {
384+ return paths;
385+ } ;
386+ config_dir. extend ( [ ".config" , "powershell" ] ) ;
387+
388+ // PowerShell provides many kinds of user-specific and host-specific
389+ // profile files. When the system has multiple profiles, PowerShell
390+ // executes them in a defined order.
391+ //
392+ // For more details, please refer to:
393+ // https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_profiles
394+ //
395+ // `~/.config/powershell/profile.ps1` is the "Current User, All Hosts"
396+ // profile file. It affects all PowerShell hosts of the current user.
397+ paths. push ( config_dir. join ( "profile.ps1" ) ) ;
398+
399+ let Ok ( config_dir) = config_dir. read_dir ( ) else {
400+ return paths;
401+ } ;
402+
403+ // Some editors like Visual Studio Code or PowerShell ISE use their
404+ // own dedicated profile files, whose file names are
405+ // `<Host Profile ID>_profile.ps1`. Such customization may use
406+ // PowerShell Editor Services for IDE integration.
407+ // https://github.com/PowerShell/PowerShellEditorServices
408+ for host_profile in config_dir {
409+ let Ok ( host_profile) = host_profile else {
410+ continue ;
411+ } ;
412+ let host_profile_path = host_profile. path ( ) ;
413+ if !host_profile_path. is_file ( ) {
414+ continue ;
415+ }
416+ if host_profile_path. ends_with ( "_profile.ps1" ) {
417+ paths. push ( host_profile_path) ;
418+ }
419+ }
420+
421+ paths
422+ }
423+
424+ fn update_rcs ( & self , process : & Process ) -> Vec < PathBuf > {
425+ let mut paths = vec ! [ ] ;
426+ // Always modify the "Current User, All Hosts" profile.
427+ let Some ( mut profile) = process. home_dir ( ) else {
428+ return paths;
429+ } ;
430+
431+ profile. extend ( [ ".config" , "powershell" , "profile.ps1" ] ) ;
432+ paths. push ( profile) ;
433+ paths
434+ }
435+
436+ fn env_script ( & self ) -> ShellScript {
437+ ShellScript {
438+ name : "env.ps1" ,
439+ content : include_str ! ( "env.ps1" ) ,
440+ }
441+ }
442+
443+ fn source_string ( & self , process : & Process ) -> Result < String > {
444+ Ok ( format ! ( r#". "{}/env.ps1""# , self . cargo_home_str( process) ?) )
445+ }
446+ }
447+
371448pub ( crate ) fn legacy_paths ( process : & Process ) -> impl Iterator < Item = PathBuf > + ' _ {
372449 let zprofiles = Zsh :: zdotdir ( process)
373450 . into_iter ( )
0 commit comments