Skip to main content

vs_shell/
activate.rs

1use crate::ShellError;
2
3/// Supported interactive shells.
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum ShellKind {
6    /// POSIX bash shell.
7    Bash,
8    /// Z shell.
9    Zsh,
10    /// Fish shell.
11    Fish,
12    /// Nushell.
13    Nushell,
14    /// PowerShell.
15    Pwsh,
16    /// Clink on Windows CMD.
17    Clink,
18}
19
20impl ShellKind {
21    /// Parses a shell kind from a CLI string.
22    pub fn parse(input: &str) -> Result<Self, ShellError> {
23        match input {
24            "bash" => Ok(Self::Bash),
25            "zsh" => Ok(Self::Zsh),
26            "fish" => Ok(Self::Fish),
27            "nushell" => Ok(Self::Nushell),
28            "pwsh" | "powershell" => Ok(Self::Pwsh),
29            "clink" => Ok(Self::Clink),
30            _ => Err(ShellError::UnknownShell(input.to_string())),
31        }
32    }
33}
34
35/// Renders the activation script for a shell.
36pub fn render_activation(shell: ShellKind) -> String {
37    match shell {
38        ShellKind::Bash => String::from(
39            r#"vs_activate() {
40  export VS_SESSION_ID="${VS_SESSION_ID:-$$}"
41  eval "$(vs __hook-env bash)"
42}
43PROMPT_COMMAND="vs_activate${PROMPT_COMMAND:+;$PROMPT_COMMAND}"
44"#,
45        ),
46        ShellKind::Zsh => String::from(
47            r#"vs_activate() {
48  export VS_SESSION_ID="${VS_SESSION_ID:-$$}"
49  eval "$(vs __hook-env zsh)"
50}
51autoload -U add-zsh-hook
52add-zsh-hook chpwd vs_activate
53precmd_functions+=(vs_activate)
54"#,
55        ),
56        ShellKind::Fish => String::from(
57            r#"function __vs_activate --on-variable PWD
58    if not set -q VS_SESSION_ID
59        set -gx VS_SESSION_ID $fish_pid
60    end
61    eval (vs __hook-env fish)
62end
63__vs_activate
64"#,
65        ),
66        ShellKind::Nushell => String::from(
67            r#"$env.VS_SESSION_ID = ($env.VS_SESSION_ID? | default $"(sys host | get pid)")
68def --env __vs_activate [] {
69  vs __hook-env nushell | lines | each {|line| load-env ($line | from json) }
70}
71__vs_activate
72"#,
73        ),
74        ShellKind::Pwsh => String::from(
75            r#"$env:VS_SESSION_ID = if ($env:VS_SESSION_ID) { $env:VS_SESSION_ID } else { $PID.ToString() }
76function global:Invoke-VsActivate {
77  Invoke-Expression (& vs __hook-env pwsh)
78}
79Invoke-VsActivate
80"#,
81        ),
82        ShellKind::Clink => String::from(
83            r#"set VS_SESSION_ID=%VS_SESSION_ID%
84if "%VS_SESSION_ID%"=="" set VS_SESSION_ID=%RANDOM%
85for /f "delims=" %%i in ('vs __hook-env clink') do %%i
86"#,
87        ),
88    }
89}