Skip to content

Commit b86b8e1

Browse files
committed
fix: tweak startup script generation
1 parent f92d94b commit b86b8e1

File tree

6 files changed

+92
-24
lines changed

6 files changed

+92
-24
lines changed

src/extension.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,12 @@ export async function activate(context: ExtensionContext): Promise<PythonEnviron
9595

9696
const terminalActivation = new TerminalActivationImpl();
9797
const shellStartupProviders = isWindows()
98-
? [new PwshStartupProvider(), new GitBashStartupProvider(), new CmdStartupProvider()]
98+
? [
99+
new PwshStartupProvider(),
100+
new GitBashStartupProvider(),
101+
new CmdStartupProvider(),
102+
new NuShellStartupProvider(),
103+
]
99104
: [
100105
new PwshStartupProvider(),
101106
new BashStartupProvider(),

src/features/terminal/startup/bashStartup.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ export class ZshStartupProvider implements ShellStartupProvider {
375375

376376
export class GitBashStartupProvider implements ShellStartupProvider {
377377
public readonly name: string = 'git-bash';
378-
private readonly gitBashActivationEnvVarKey = 'VSCODE_GIT_BASH_ACTIVATE';
378+
private readonly gitBashActivationEnvVarKey = 'VSCODE_BASH_ACTIVATE';
379379

380380
private async checkShellInstalled(): Promise<boolean> {
381381
const found = await isGitBashInstalled();
@@ -444,6 +444,7 @@ export class GitBashStartupProvider implements ShellStartupProvider {
444444
}
445445
async removeEnvVariables(envVars: EnvironmentVariableCollection): Promise<void> {
446446
envVars.delete(this.gitBashActivationEnvVarKey);
447+
envVars.delete('VSCODE_GIT_BASH_ACTIVATE');
447448
}
448449
async getEnvVariables(env?: PythonEnvironment): Promise<Map<string, string | undefined> | undefined> {
449450
if (!env) {

src/features/terminal/startup/cmdStartup.ts

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,6 @@ async function getExistingAutoRun(): Promise<string | undefined> {
118118
const match = stdout.match(/AutoRun\s+REG_SZ\s+(.*)/);
119119
if (match && match[1]) {
120120
const content = match[1].trim();
121-
// Don't return our own batch file calls
122-
if (content.includes('cmd_startup.bat')) {
123-
return undefined;
124-
}
125121
return content;
126122
}
127123
} catch {
@@ -182,14 +178,16 @@ async function setupCmdStartup(cmdFiles: CmdFilePaths, key: string): Promise<boo
182178
// Step 1: Create or update the activation file
183179
if (!(await fs.pathExists(cmdFiles.startupFile))) {
184180
await fs.writeFile(cmdFiles.startupFile, activationContent);
185-
traceInfo(`Created new CMD activation file at: ${cmdFiles.startupFile}\r\n${activationContent}`);
181+
traceInfo(`SHELL: Created new CMD activation file at: ${cmdFiles.startupFile}\r\n${activationContent}`);
186182
} else {
187183
const content = await fs.readFile(cmdFiles.startupFile, 'utf8');
188184
if (!content.includes(key)) {
189185
await fs.writeFile(cmdFiles.startupFile, `${content}${activationContent}`);
190-
traceInfo(`Updated existing CMD activation file at: ${cmdFiles.startupFile}\r\n${activationContent}`);
186+
traceInfo(
187+
`SHELL: Updated existing CMD activation file at: ${cmdFiles.startupFile}\r\n${activationContent}`,
188+
);
191189
} else {
192-
traceInfo(`CMD activation file at ${cmdFiles.startupFile} already contains activation code`);
190+
traceInfo(`SHELL: CMD activation file at ${cmdFiles.startupFile} already contains activation code`);
193191
}
194192
}
195193

@@ -198,13 +196,21 @@ async function setupCmdStartup(cmdFiles: CmdFilePaths, key: string): Promise<boo
198196

199197
// Step 3: Create or update the main batch file
200198
const mainBatchContent = getMainBatchFileContent(cmdFiles.regStartupFile, existingAutoRun);
201-
await fs.writeFile(cmdFiles.mainBatchFile, mainBatchContent);
202-
traceInfo(`Created/Updated main batch file at: ${cmdFiles.mainBatchFile}`);
199+
if (mainBatchContent.includes(cmdFiles.regMainBatchFile) || mainBatchContent.includes(cmdFiles.mainBatchFile)) {
200+
traceInfo(`SHELL: CMD main batch file already contains our startup file`);
201+
} else {
202+
await fs.writeFile(cmdFiles.mainBatchFile, mainBatchContent);
203+
traceInfo(`SHELL: Created/Updated main batch file at: ${cmdFiles.mainBatchFile}`);
204+
}
203205

204206
// Step 4: Setup registry AutoRun to call our main batch file
205-
const registrySetup = await setupRegistryAutoRun(cmdFiles.mainBatchFile);
206-
207-
return registrySetup;
207+
if (existingAutoRun?.includes(cmdFiles.regMainBatchFile) || existingAutoRun?.includes(cmdFiles.mainBatchFile)) {
208+
traceInfo(`SHELL: CMD AutoRun registry key already contains our main batch file`);
209+
} else {
210+
const registrySetup = await setupRegistryAutoRun(cmdFiles.mainBatchFile);
211+
return registrySetup;
212+
}
213+
return true;
208214
} catch (err) {
209215
traceVerbose(`Failed to setup CMD startup`, err);
210216
return false;

src/features/terminal/startup/fishStartup.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ async function isFishInstalled(): Promise<boolean> {
2222
async function getFishProfile(): Promise<string> {
2323
const homeDir = os.homedir();
2424
// Fish configuration is typically at ~/.config/fish/config.fish
25-
return path.join(homeDir, '.config', 'fish', 'config.fish');
25+
const profilePath = path.join(homeDir, '.config', 'fish', 'config.fish');
26+
traceInfo(`SHELL: fish profile found at: ${profilePath}`);
27+
return profilePath;
2628
}
2729

2830
const regionStart = '# >>> vscode python';
@@ -55,16 +57,16 @@ async function setupStartup(profilePath: string, key: string): Promise<boolean>
5557
if (!(await fs.pathExists(profilePath))) {
5658
// Create new profile with our content
5759
await fs.writeFile(profilePath, activationContent);
58-
traceInfo(`Created new fish profile at: ${profilePath}\n${activationContent}`);
60+
traceInfo(`SHELL: Created new fish profile at: ${profilePath}\n${activationContent}`);
5961
} else {
6062
// Update existing profile
6163
const content = await fs.readFile(profilePath, 'utf8');
6264
if (!content.includes(key)) {
6365
await fs.writeFile(profilePath, `${content}${activationContent}`);
64-
traceInfo(`Updated existing fish profile at: ${profilePath}\n${activationContent}`);
66+
traceInfo(`SHELL: Updated existing fish profile at: ${profilePath}\n${activationContent}`);
6567
} else {
6668
// Already contains our activation code
67-
traceInfo(`Fish profile at ${profilePath} already contains activation code`);
69+
traceInfo(`SHELL: Fish profile at ${profilePath} already contains activation code`);
6870
}
6971
}
7072
return true;

src/features/terminal/startup/nuShellStartup.ts

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,67 @@ import { quoteArgs } from '../../execution/execUtils';
99
import { traceError, traceInfo, traceVerbose } from '../../../common/logging';
1010
import which from 'which';
1111
import { ShellConstants } from '../../common/shellConstants';
12+
import { runCommand } from './utils';
13+
import { isWindows } from '../../../common/utils/platformUtils';
1214

1315
async function isNuShellInstalled(): Promise<boolean> {
1416
try {
15-
await which('nu');
17+
const binPath = await which('nu');
18+
traceInfo(`SHELL: Nu shell binary found at ${binPath}`);
1619
return true;
1720
} catch {
1821
return false;
1922
}
2023
}
2124

25+
async function getDefaultConfigPath(): Promise<string | undefined> {
26+
try {
27+
const configPath = await runCommand('nu -c $nu.default-config-dir');
28+
29+
return configPath ? configPath.trim() : undefined;
30+
} catch (err) {
31+
traceError(`Failed to get default config path`, err);
32+
return undefined;
33+
}
34+
}
35+
2236
async function getNuShellProfile(): Promise<string> {
23-
const homeDir = os.homedir();
24-
// Nu shell configuration is typically at ~/.config/nushell/config.nu
25-
return path.join(homeDir, '.config', 'nushell', 'config.nu');
37+
const pathsToCheck: string[] = [];
38+
39+
const defaultConfigPath = await getDefaultConfigPath();
40+
if (defaultConfigPath) {
41+
pathsToCheck.push(path.join(defaultConfigPath, 'config.nu'));
42+
}
43+
44+
if (isWindows()) {
45+
const appDataPath = process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming');
46+
pathsToCheck.push(path.join(appDataPath, 'nushell', 'config.nu'), path.join(appDataPath, 'nu', 'config.nu'));
47+
}
48+
49+
pathsToCheck.push(
50+
path.join(os.homedir(), '.config', 'nushell', 'config.nu'),
51+
path.join(os.homedir(), '.config', 'nu', 'config.nu'),
52+
path.join(os.homedir(), '.nushell', 'config.nu'),
53+
path.join(os.homedir(), '.nu', 'config.nu'),
54+
);
55+
56+
for (const profilePath of pathsToCheck) {
57+
if (await fs.pathExists(profilePath)) {
58+
traceInfo(`SHELL: Nu shell profile found at ${profilePath}`);
59+
return profilePath;
60+
}
61+
}
62+
63+
// Nothing worked so return the default path
64+
if (isWindows()) {
65+
const defaultPath = path.join(os.homedir(), 'AppData', 'Roaming', 'nushell', 'config.nu');
66+
traceInfo(`SHELL: Nu shell profile not found, using default path ${defaultPath}`);
67+
return defaultPath;
68+
}
69+
70+
const defaultPath = path.join(os.homedir(), '.config', 'nushell', 'config.nu');
71+
traceInfo(`SHELL: Nu shell profile not found, using default path ${defaultPath}`);
72+
return defaultPath;
2673
}
2774

2875
const regionStart = '# >>> vscode python';

src/features/terminal/startup/powershellStartup.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ async function getProfileForShell(shell: 'powershell' | 'pwsh'): Promise<PowerSh
3333
traceVerbose(`${shell} is not available or failed to get profile path`);
3434
return undefined;
3535
}
36+
traceInfo(`SHELL: ${shell} profile found at: ${profilePath}`);
3637
return { shell, profilePath };
3738
} catch (err) {
3839
traceVerbose(`${shell} is not available or failed to get profile path`, err);
@@ -98,17 +99,23 @@ async function setupPowerShellStartup(key: string): Promise<boolean> {
9899
if (!(await fs.pathExists(profile.profilePath))) {
99100
// Create new profile with our content
100101
await fs.writeFile(profile.profilePath, activationContent);
101-
traceInfo(`Created new ${profile.shell} profile at: ${profile.profilePath}\r\n${activationContent}`);
102+
traceInfo(
103+
`SHELL: Created new ${profile.shell} profile at: ${profile.profilePath}\r\n${activationContent}`,
104+
);
102105
successfulUpdates++;
103106
} else {
104107
// Update existing profile
105108
const content = await fs.readFile(profile.profilePath, 'utf8');
106109
if (!content.includes(key)) {
107110
await fs.writeFile(profile.profilePath, `${content}${activationContent}`);
108111
traceInfo(
109-
`Updated existing ${profile.shell} profile at: ${profile.profilePath}\r\n${activationContent}`,
112+
`SHELL: Updated existing ${profile.shell} profile at: ${profile.profilePath}\r\n${activationContent}`,
110113
);
111114
successfulUpdates++;
115+
} else {
116+
traceInfo(
117+
`SHELL: ${profile.shell} profile at ${profile.profilePath} already contains activation code`,
118+
);
112119
}
113120
}
114121
} catch (err) {

0 commit comments

Comments
 (0)