@@ -6,23 +6,31 @@ use File::Spec;
66use NVMPL::Config;
77use NVMPL::Utils qw( detect_platform) ;
88
9-
109# ---------------------------------------------------------
1110# Public entry point
1211# ---------------------------------------------------------
1312
1413sub _detect_shell {
15- my $shell = $ENV {SHELL } || ' /bin/bash' ;
16- if ($shell =~ / zsh/ ) {
14+ # --- Windows shell detection first ---
15+ if ($^O eq ' MSWin32' ) {
16+ # PowerShell defines PSModulePath, CMD defines ComSpec
17+ if ($ENV {PSModulePath }) {
18+ return ' PowerShell' ;
19+ } elsif ($ENV {ComSpec } && $ENV {ComSpec } =~ / cmd\. exe/i ) {
20+ return ' Cmd' ;
21+ } else {
22+ return ' PowerShell' ; # safe default on Windows
23+ }
24+ }
25+
26+ # --- Unix-like environments ---
27+ my $shell = $ENV {SHELL } || ' ' ;
28+ if ($shell =~ / zsh/i ) {
1729 return ' Zsh' ;
18- } elsif ($shell =~ / bash/ ) {
30+ } elsif ($shell =~ / bash/i ) {
1931 return ' Bash' ;
20- } elsif ($shell =~ / cmd\. exe/i || $^O eq ' MSWin32' ) {
21- return ' Cmd' ;
22- } elsif ($shell =~ / powershell|pwsh/i ) {
23- return ' PowerShell' ;
2432 } else {
25- return ' Bash' ;
33+ return ' Bash' ; # fallback for unknown shells
2634 }
2735}
2836
@@ -37,12 +45,21 @@ sub use_version {
3745 my $vtag = " v$version " ;
3846
3947 my $cfg = NVMPL::Config-> load();
40- my $install_dir = $cfg -> {install_dir };
48+ my $install_dir = $cfg -> {install_dir };
4149 my $versions_dir = File::Spec-> catdir($install_dir , ' versions' );
42- my $target_dir = File::Spec-> catdir($versions_dir , $vtag );
50+ my $target_dir = File::Spec-> catdir($versions_dir , $vtag );
51+
52+ # --- Windows nested node folder fix ---
53+ if ($^O eq ' MSWin32' ) {
54+ my @matches = glob (" $target_dir \\ node-v*-win-x64" );
55+ if (@matches && -d $matches [0]) {
56+ $target_dir = $matches [0];
57+ }
58+ }
59+
4360 my $current_link = File::Spec-> catfile($versions_dir , ' current' );
4461
45- unless (-d $target_dir ) {
62+ unless (-d $target_dir ) {
4663 say " [nvm-pl] Version $vtag is not installed." ;
4764 return 1;
4865 }
@@ -61,33 +78,60 @@ sub use_version {
6178 _update_shell_config($current_link );
6279
6380 say " [nvm-pl] Active version is now $vtag " ;
64- say " Restart your shell or run the appropriate source command for your shell." ;
6581
82+ # --- PowerShell live PATH update ---
83+ if ($^O eq ' MSWin32' && $ENV {PSModulePath }) {
84+ my $ps_path = $target_dir ;
85+ $ps_path =~ s # /# \\ # g ;
86+
87+ # only update if node.exe isn't already on PATH
88+ my $node_check = ` where node 2> NUL` ;
89+ if ($node_check !~ / \Q $ps_path \E /i ) {
90+ # Detect which PowerShell to use
91+ my $ps_exe = ` where pwsh 2> NUL` ;
92+ chomp ($ps_exe );
93+ if (!$ps_exe ) {
94+ $ps_exe = ` where powershell 2> NUL` ;
95+ chomp ($ps_exe );
96+ }
97+
98+ if ($ps_exe ) {
99+ say " [nvm-pl] (PowerShell) Updating PATH for current session..." ;
100+ system ($ps_exe , " -NoLogo" , " -NoProfile" , " -Command" ,
101+ " \$ env:PATH = '$ps_path ;' + \$ env:PATH; Write-Host 'PATH updated for this session.'" );
102+ } else {
103+ say " [nvm-pl] (PowerShell) Could not find PowerShell executable — skipping live PATH update." ;
104+ }
105+ } else {
106+ say " [nvm-pl] (PowerShell) Node path already active." ;
107+ }
108+ }
109+
110+ say " Restart your shell or run the appropriate source command for your shell." ;
66111 return 0;
67112}
68113
114+
69115sub _update_shell_config {
70116 my ($current_link ) = @_ ;
71117 my $shell_type = _detect_shell();
72-
73- # Load the appropriate shell module
118+
119+ # Load the appropriate shell module dynamically
74120 my $shell_module = " NVMPL::Shell::$shell_type " ;
75121 eval " require $shell_module " or do {
76122 warn " [nvm-pl] Could not load $shell_module : $@ " ;
77123 return ;
78124 };
79-
125+
80126 my $init_snippet = $shell_module -> init_snippet();
81-
82- # Update the appropriate config file
83- my $config_file = _get_shell_config($shell_type );
127+ my $config_file = _get_shell_config($shell_type );
84128 _write_shell_config($config_file , $init_snippet , $shell_type );
85129}
86130
87131sub _get_shell_config {
88132 my ($shell_type ) = @_ ;
89- my $home = $ENV {HOME };
90-
133+ my $home = $ENV {HOME } // $ENV { USERPROFILE } ;
134+
91135 return {
92136 Bash => " $home /.bashrc" ,
93137 Zsh => " $home /.zshrc" ,
@@ -98,60 +142,56 @@ sub _get_shell_config {
98142
99143sub _write_shell_config {
100144 my ($config_file , $init_snippet , $shell_type ) = @_ ;
101-
102145 return unless $config_file ;
103-
146+
104147 # Read existing config
105148 my @lines ;
106149 if (-f $config_file ) {
107150 open my $in , ' <' , $config_file or return ;
108151 @lines = <$in >;
109152 close $in ;
110153 }
111-
154+
112155 # Remove ONLY the nvm-pl managed section (more precise)
113156 my @clean_lines ;
114157 my $in_nvm_section = 0;
115-
158+
116159 foreach my $line (@lines ) {
117160 # Detect start of nvm-pl section
118161 if ($line =~ / ^# nvm-pl managed Node\. js path$ / ) {
119162 $in_nvm_section = 1;
120163 next ;
121164 }
122-
165+
123166 # Skip lines until we're out of the nvm-pl section
124167 if ($in_nvm_section ) {
125- # Detect end of nvm-pl section (empty line or new section)
126168 if ($line =~ / ^\s *$ / || $line =~ / ^#/ ) {
127169 $in_nvm_section = 0;
128170 } else {
129171 next ;
130172 }
131173 }
132-
133- # Keep the line if we're not in nvm-pl section
174+
134175 push @clean_lines , $line unless $in_nvm_section ;
135176 }
136-
177+
137178 # Write new config with nvm-pl snippet at the end
138179 open my $out , ' >' , $config_file or return ;
139180 print $out @clean_lines ;
140181 print $out " \n # nvm-pl managed Node.js path\n " ;
141182 print $out " $init_snippet \n " ;
142183 close $out ;
143-
184+
144185 say " [nvm-pl] Updated $config_file for $shell_type " ;
145186}
146187
147-
148188# ---------------------------------------------------------
149189# Helpers
150190# ---------------------------------------------------------
151191
152192sub _win_junction {
153193 my ($link , $target ) = @_ ;
154- $link =~ s # /# \\ # g ;
194+ $link =~ s # /# \\ # g ;
155195 $target =~ s # /# \\ # g ;
156196 my $cmd = " cmd /C mklink /J \" $link \" \" $target \" " ;
157197 system ($cmd ) == 0
@@ -195,4 +235,4 @@ sub _get_current_version {
195235 return undef ;
196236}
197237
198- 1;
238+ 1;
0 commit comments